Repository: pivotal/cedar Branch: master Commit: 176a091e663c Files: 338 Total size: 1.6 MB Directory structure: gitextract_0axu_sjl/ ├── .gitignore ├── .travis.yml ├── Cedar-Info.plist ├── Cedar.podspec ├── Cedar.xcodeproj/ │ ├── project.pbxproj │ └── xcshareddata/ │ └── xcschemes/ │ ├── Cedar-OSX SpecBundle.xcscheme │ ├── Cedar-OSX Specs.xcscheme │ ├── Cedar-OSX.xcscheme │ ├── Cedar-iOS SpecBundle.xcscheme │ ├── Cedar-iOS StaticFramework.xcscheme │ ├── Cedar-iOS StaticLib.xcscheme │ ├── Cedar-iOS.xcscheme │ ├── Cedar-tvOS SpecBundle.xcscheme │ ├── Cedar-tvOS.xcscheme │ ├── Cedar-watchOS Specs.xcscheme │ └── Cedar-watchOS.xcscheme ├── CodeSnippetsAndTemplates/ │ ├── AppCodeSnippets/ │ │ └── Cedar.xml │ ├── CodeSnippets/ │ │ ├── caft-swift.codesnippet │ │ ├── caft.codesnippet │ │ ├── cbef-swift.codesnippet │ │ ├── cbef.codesnippet │ │ ├── cbl-context.codesnippet │ │ ├── cbl-swift.codesnippet │ │ ├── cbl.codesnippet │ │ ├── cblcont-swift.codesnippet │ │ ├── ccont-swift.codesnippet │ │ ├── ccont.codesnippet │ │ ├── cdesc-swift.codesnippet │ │ ├── cdesc.codesnippet │ │ ├── cexpandpend-swift.codesnippet │ │ ├── cexpandpend.codesnippet │ │ ├── cit-swift.codesnippet │ │ ├── cit.codesnippet │ │ ├── clog-swift.codesnippet │ │ ├── clog.codesnippet │ │ ├── cpend-swift.codesnippet │ │ ├── cpend.codesnippet │ │ ├── cshare-swift.codesnippet │ │ ├── cshare.codesnippet │ │ ├── csubj-swift.codesnippet │ │ └── csubj.codesnippet │ └── Templates/ │ └── File Templates/ │ └── Cedar/ │ └── Cedar Spec.xctemplate/ │ ├── Objective-C++/ │ │ └── ___FILEBASENAME___Spec.mm │ ├── Swift/ │ │ └── ___FILEBASENAME___Spec.swift │ └── TemplateInfo.plist ├── English.lproj/ │ └── InfoPlist.strings ├── Gemfile ├── MIT.LICENSE.txt ├── README.markdown ├── Rakefile ├── Source/ │ ├── CDRExample.m │ ├── CDRExampleBase.m │ ├── CDRExampleGroup.m │ ├── CDRFunctions.m │ ├── CDRNil.m │ ├── CDRRunState.m │ ├── CDRRuntimeUtilities.m │ ├── CDRSharedExampleGroupPool.m │ ├── CDRSpec.m │ ├── CDRSpecFailure.m │ ├── CDRSpecHelper.m │ ├── CDRSpecRun.m │ ├── CDRStateTracker.h │ ├── CDRStateTracker.m │ ├── CDRStateTracking.h │ ├── CDRSymbolicator.m │ ├── CDRTestBundleRunner.m │ ├── CDRTypeUtilities.m │ ├── Doubles/ │ │ ├── Arguments/ │ │ │ ├── AnyArgument.mm │ │ │ ├── AnyInstanceArgument.mm │ │ │ ├── AnyInstanceConformingToProtocolArgument.mm │ │ │ └── AnyInstanceOfClassArgument.mm │ │ ├── CDRClassFake.mm │ │ ├── CDRFake.mm │ │ ├── CDRProtocolFake.mm │ │ ├── CDRSpy.mm │ │ ├── CDRSpyInfo.mm │ │ ├── CedarDouble.mm │ │ ├── CedarDoubleImpl.mm │ │ ├── HaveReceived.mm │ │ ├── InvocationMatcher.mm │ │ ├── RejectedMethod.mm │ │ └── StubbedMethod.mm │ ├── Extensions/ │ │ ├── NSInvocation+Cedar.m │ │ └── NSMethodSignature+Cedar.m │ ├── Headers/ │ │ ├── Project/ │ │ │ ├── CDRBlockHelper.h │ │ │ ├── CDRNil.h │ │ │ ├── CDRPrivateFunctions.h │ │ │ ├── CDRRunState.h │ │ │ ├── CDRRuntimeUtilities.h │ │ │ ├── CDRSpecRun.h │ │ │ ├── CDRSymbolicator.h │ │ │ ├── CDRTypeUtilities.h │ │ │ ├── Doubles/ │ │ │ │ ├── CDRSpyInfo.h │ │ │ │ └── CedarDoubleImpl.h │ │ │ ├── Extensions/ │ │ │ │ ├── NSInvocation+Cedar.h │ │ │ │ └── NSMethodSignature+Cedar.h │ │ │ ├── ReporterHelpers/ │ │ │ │ ├── CDROTestNamer.h │ │ │ │ └── CDRSlowTestStatistics.h │ │ │ ├── Reporters/ │ │ │ │ └── CDRReportDispatcher.h │ │ │ └── XCTest/ │ │ │ ├── CDRXCTestCase.h │ │ │ ├── CDRXCTestObserver.h │ │ │ ├── CDRXCTestSuite.h │ │ │ ├── CDRXCTestSupport.h │ │ │ └── NSInvocation+CDRXExample.h │ │ └── Public/ │ │ ├── CDRExample.h │ │ ├── CDRExampleBase.h │ │ ├── CDRExampleGroup.h │ │ ├── CDRExampleParent.h │ │ ├── CDRFunctions.h │ │ ├── CDRHooks.h │ │ ├── CDRNullabilityCompat.h │ │ ├── CDRSharedExampleGroupPool.h │ │ ├── CDRSpec.h │ │ ├── CDRSpecFailure.h │ │ ├── CDRSpecHelper.h │ │ ├── CDRVersion.h │ │ ├── Cedar.h │ │ ├── Doubles/ │ │ │ ├── Arguments/ │ │ │ │ ├── AnyArgument.h │ │ │ │ ├── AnyInstanceArgument.h │ │ │ │ ├── AnyInstanceConformingToProtocolArgument.h │ │ │ │ ├── AnyInstanceOfClassArgument.h │ │ │ │ ├── Argument.h │ │ │ │ ├── ReturnValue.h │ │ │ │ └── ValueArgument.h │ │ │ ├── CDRClassFake.h │ │ │ ├── CDRFake.h │ │ │ ├── CDRProtocolFake.h │ │ │ ├── CDRSpy.h │ │ │ ├── CedarDouble.h │ │ │ ├── CedarDoubles.h │ │ │ ├── HaveReceived.h │ │ │ ├── InvocationMatcher.h │ │ │ ├── RejectedMethod.h │ │ │ └── StubbedMethod.h │ │ ├── Matchers/ │ │ │ ├── ActualValue.h │ │ │ ├── Base/ │ │ │ │ ├── Base.h │ │ │ │ ├── BeCloseTo.h │ │ │ │ ├── BeFalsy.h │ │ │ │ ├── BeGTE.h │ │ │ │ ├── BeGreaterThan.h │ │ │ │ ├── BeInstanceOf.h │ │ │ │ ├── BeLTE.h │ │ │ │ ├── BeLessThan.h │ │ │ │ ├── BeNil.h │ │ │ │ ├── BeSameInstanceAs.h │ │ │ │ ├── BeTruthy.h │ │ │ │ ├── BlockMatcher.h │ │ │ │ ├── ConformTo.h │ │ │ │ ├── Equal.h │ │ │ │ ├── Exist.h │ │ │ │ ├── RaiseException.h │ │ │ │ └── RespondTo.h │ │ │ ├── CedarComparators.h │ │ │ ├── CedarMatchers.h │ │ │ ├── CedarStringifiers.h │ │ │ ├── Comparators/ │ │ │ │ ├── AnInstanceOf.h │ │ │ │ ├── ComparatorsBase.h │ │ │ │ ├── ComparatorsContainer.h │ │ │ │ ├── ComparatorsContainerConvenience.h │ │ │ │ ├── CompareCloseTo.h │ │ │ │ ├── CompareEqual.h │ │ │ │ └── CompareGreaterThan.h │ │ │ ├── Container/ │ │ │ │ ├── BeEmpty.h │ │ │ │ ├── Contain.h │ │ │ │ └── ContainSubset.h │ │ │ ├── MatcherTemplate.h │ │ │ ├── OSX/ │ │ │ │ ├── OSXGeometryCompareEqual.h │ │ │ │ └── OSXGeometryStringifiers.h │ │ │ ├── ShouldSyntax.h │ │ │ ├── Stringifiers/ │ │ │ │ ├── StringifiersBase.h │ │ │ │ └── StringifiersContainer.h │ │ │ └── UIKit/ │ │ │ ├── UIGeometryCompareEqual.h │ │ │ ├── UIGeometryStringifiers.h │ │ │ └── iOS/ │ │ │ └── UIKitComparatorsContainer.h │ │ ├── Reporters/ │ │ │ ├── CDRBufferedDefaultReporter.h │ │ │ ├── CDRColorizedReporter.h │ │ │ ├── CDRDefaultReporter.h │ │ │ ├── CDRExampleReporter.h │ │ │ ├── CDRJUnitXMLReporter.h │ │ │ ├── CDROTestReporter.h │ │ │ ├── CDRTeamCityReporter.h │ │ │ └── CedarReporters.h │ │ └── iOS/ │ │ ├── Cedar-iOS.h │ │ └── CedarApplicationDelegate.h │ ├── Matchers/ │ │ ├── Base/ │ │ │ ├── ConformTo.mm │ │ │ ├── RaiseException.mm │ │ │ └── RespondTo.mm │ │ └── Stringifiers/ │ │ └── StringifiersBase.mm │ ├── ReporterHelpers/ │ │ ├── CDROTestNamer.m │ │ └── CDRSlowTestStatistics.m │ ├── Reporters/ │ │ ├── CDRBufferedDefaultReporter.m │ │ ├── CDRColorizedReporter.m │ │ ├── CDRDefaultReporter.m │ │ ├── CDRJUnitXMLReporter.m │ │ ├── CDROTestReporter.m │ │ ├── CDRReportDispatcher.m │ │ └── CDRTeamCityReporter.m │ ├── XCTest/ │ │ ├── CDRSpec+XCTestSupport.m │ │ ├── CDRXCTestCase.m │ │ ├── CDRXCTestFunctions.m │ │ ├── CDRXCTestObserver.m │ │ ├── CDRXCTestSuite.m │ │ └── NSInvocation+CDRXExample.m │ └── iOS/ │ ├── CedarApplicationDelegate.m │ └── NSBundle+MainBundleHijack.m ├── Spec/ │ ├── CDRExampleGroupSpec.mm │ ├── CDRExampleSpec.mm │ ├── CDRHooksSpec.mm │ ├── CDRNilSpec.mm │ ├── CDRSpecFailureSpec.mm │ ├── CDRSpecRunSpec.mm │ ├── CDRSpecSpec.mm │ ├── CDRSymbolicatorSpec.mm │ ├── CDRTypeUtilitiesSpec.mm │ ├── Doubles/ │ │ ├── CDRClassFakeSpec.mm │ │ ├── CDRProtocolFakeSpec.mm │ │ ├── CDRSpySpec.mm │ │ ├── CedarDoubleARCSharedExamples.mm │ │ ├── CedarDoubleSharedExamples.mm │ │ ├── CedarNiceFakeSharedExamples.mm │ │ ├── CedarOrdinaryFakeSharedExamples.mm │ │ └── HaveReceivedSpec.mm │ ├── Focused/ │ │ ├── FocusedSpec.m │ │ ├── FocusedSpec2.m │ │ └── main.mm │ ├── Matchers/ │ │ ├── Base/ │ │ │ ├── BeCloseToSpec.mm │ │ │ ├── BeFalsySpec.mm │ │ │ ├── BeGTESpec.mm │ │ │ ├── BeGreaterThanSpec.mm │ │ │ ├── BeInstanceOfSpec.mm │ │ │ ├── BeLTESpec.mm │ │ │ ├── BeLessThanSpec.mm │ │ │ ├── BeNilSpec.mm │ │ │ ├── BeNil_ARCSpec.mm │ │ │ ├── BeSameInstanceAsSpec.mm │ │ │ ├── BeSameInstanceAs_ARCSpec.mm │ │ │ ├── BeTruthySpec.mm │ │ │ ├── BlockMatcherSpec.mm │ │ │ ├── BlockMatcher_ARCSpecSpec.mm │ │ │ ├── ConformToSpec.mm │ │ │ ├── EqualSpec.mm │ │ │ ├── ExistSpec.mm │ │ │ ├── MutableEqualSpec.mm │ │ │ ├── RaiseExceptionSpec.mm │ │ │ └── RespondToSpec.mm │ │ ├── Container/ │ │ │ ├── BeEmptySpec.mm │ │ │ ├── ContainSpec.mm │ │ │ └── ContainSubsetSpec.mm │ │ ├── ExpectFailureWithMessage.h │ │ ├── ExpectFailureWithMessage.mm │ │ ├── OSX/ │ │ │ └── OSXGeometryEqualSpecSpec.mm │ │ └── UIKit/ │ │ ├── UIKitContainSpec.mm │ │ └── UIKitEqualSpec.mm │ ├── ObjCHeadersSpec.mm │ ├── Reporters/ │ │ ├── CDRDefaultReporterSpec.mm │ │ ├── CDRJUnitXMLReporterSpec.mm │ │ └── CDROTestReporterSpec.mm │ ├── ShouldSyntaxSpec.mm │ ├── SpecBundle/ │ │ ├── OS X Host App/ │ │ │ ├── Info.plist │ │ │ └── main.m │ │ ├── SpecBundle-Info.plist │ │ ├── SpecBundleApplicationTests.mm │ │ ├── SpecBundleApplicationTestsWithXCTest.m │ │ ├── Support/ │ │ │ ├── TestObservationHelper.h │ │ │ └── TestObservationHelper.m │ │ └── iOS Host App/ │ │ ├── en.lproj/ │ │ │ └── DummyView.xib │ │ ├── iOSHostAppDelegate.h │ │ ├── iOSHostAppDelegate.m │ │ └── main.m │ ├── SpecSpec.mm │ ├── SpecSpec2.m │ ├── Support/ │ │ ├── ARCViewController.h │ │ ├── ARCViewController.m │ │ ├── ArgumentReleaser.h │ │ ├── ArgumentReleaser.m │ │ ├── CedarObservedObject.h │ │ ├── CedarTestSpecBuilder.h │ │ ├── CedarTestSpecBuilder.m │ │ ├── DeallocNotifier.h │ │ ├── DeallocNotifier.m │ │ ├── ExampleWithPublicRunDates.h │ │ ├── ExampleWithPublicRunDates.mm │ │ ├── FibonacciCalculator.h │ │ ├── FibonacciCalculator.m │ │ ├── FooSuperclass.h │ │ ├── FooSuperclass.m │ │ ├── GData/ │ │ │ ├── GDataXMLNode.h │ │ │ └── GDataXMLNode.m │ │ ├── ObjectWithCollections.h │ │ ├── ObjectWithCollections.m │ │ ├── ObjectWithForwardingTarget.h │ │ ├── ObjectWithForwardingTarget.m │ │ ├── ObjectWithProperty.h │ │ ├── ObjectWithProperty.m │ │ ├── ObjectWithValueEquality.h │ │ ├── ObjectWithValueEquality.m │ │ ├── ObjectWithWeakDelegate.h │ │ ├── ObjectWithWeakDelegate.m │ │ ├── SimpleIncrementer.h │ │ ├── SimpleIncrementer.m │ │ ├── SimpleKeyValueObserver.h │ │ ├── SimpleKeyValueObserver.m │ │ ├── SimpleMultiplier.h │ │ ├── TestReporter.h │ │ └── TestReporter.m │ ├── Swift/ │ │ ├── Spec-Bridging-Header.h │ │ ├── SwiftSpec.swift │ │ └── XCTAssertSpec.swift │ ├── XCTest/ │ │ └── CDRXCTestSuiteSpec.mm │ ├── iOS/ │ │ ├── CDRSpyiOSSpec.mm │ │ ├── Cedar-iOSSpec.mm │ │ ├── CedarApplicationDelegateSpec.mm │ │ ├── Info.plist │ │ ├── WeakReferenceCompatibilitySpec.mm │ │ ├── XCTest/ │ │ │ └── CDRXTestSuiteSpec.mm │ │ └── main.mm │ ├── main.mm │ └── watchOS/ │ ├── App-Info.plist │ ├── Extension-Info.plist │ ├── ExtensionDelegate.mm │ └── Interface.storyboard ├── install.sh ├── installCodeSnippetsAndTemplates ├── scripts/ │ ├── rake/ │ │ ├── helpers/ │ │ │ ├── appcode.rb │ │ │ ├── shell.rb │ │ │ ├── simulator.rb │ │ │ └── xcode.rb │ │ ├── helpers.rb │ │ ├── tasks/ │ │ │ ├── default.rb │ │ │ ├── dist.rb │ │ │ ├── frameworks.rb │ │ │ ├── install.rb │ │ │ ├── spec_suites.rb │ │ │ ├── test_bundles.rb │ │ │ └── versioning.rb │ │ └── tasks.rb │ └── set_git_sha_on_framework.rb └── upgradeCedarFramework ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.mode1v3 *.pbxuser *.xcworkspace xcuserdata build .DS_Store .idea template-project DerivedData ================================================ FILE: .travis.yml ================================================ language: objective-c env: matrix: - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="7.0.3" TASK="rake ci" - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="7.1" TASK="rake ci" - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="8.1" TASK="rake ci" # Analyze takes too long -- vary on runtime SDK - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="8.1" TASK="rake suites:specs:analyze" - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="8.1" TASK="rake suites:uispecs:analyze" - CEDAR_SDK_VERSION="8.1" CEDAR_SDK_RUNTIME_VERSION="8.1" TASK="rake suites:focused_specs:analyze" - TASK="./install.sh" - TASK="./installCodeSnippetsAndTemplates" before_install: brew update install: - bundle install - brew install ios-sim script: # run a printer task to keep travis from terminating static analysis - 'while true; do echo "(waiting)"; sleep 60; done &' - $TASK - kill %1 ================================================ FILE: Cedar-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 NSPrincipalClass ================================================ FILE: Cedar.podspec ================================================ Pod::Spec.new do |s| s.name = 'Cedar' s.version = '1.0' s.license = 'MIT' s.summary = 'BDD-style testing using Objective-C.' s.homepage = 'https://github.com/cedarbdd/cedar' s.author = { 'Pivotal Labs' => 'http://pivotallabs.com' } s.license = { :type => 'MIT', :file => 'MIT.LICENSE.txt' } s.source = { :git => 'https://github.com/cedarbdd/cedar.git', :tag => "v#{s.version}" } s.osx.deployment_target = '10.7' s.ios.deployment_target = '6.0' s.watchos.deployment_target = '2.0' s.source_files = 'Source/**/*.{h,m,mm}' s.public_header_files = 'Source/Headers/Public/**/*.{h}' s.osx.exclude_files = '**/{iOS,UIKit}/**' s.ios.exclude_files = '**/OSX/**' s.watchos.exclude_files = '**/{OSX,iOS}/**' s.tvos.deployment_target = '9.0' s.tvos.exclude_files = '**/OSX/**' # Versions of this pod >= 0.9.0 require C++11. # https://github.com/cedarbdd/cedar/issues/47 s.xcconfig = { 'CLANG_CXX_LANGUAGE_STANDARD' => 'c++0x', 'CLANG_CXX_LIBRARY' => 'libc++', 'OTHER_CFLAGS' => '-DDEVELOPER_BIN_DIR=@\"${DEVELOPER_BIN_DIR}\"' } s.libraries = 'c++' s.requires_arc = false end ================================================ FILE: Cedar.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ AEEE224B11DC2BBB00029872 /* Cedar-iOS StaticFramework */ = { isa = PBXAggregateTarget; buildConfigurationList = AEEE225311DC2BC000029872 /* Build configuration list for PBXAggregateTarget "Cedar-iOS StaticFramework" */; buildPhases = ( AEEE225511DC2BD700029872 /* Build architecture-specific static libs */, AEEE225A11DC2C0200029872 /* Build universal static lib */, AEEE225E11DC2C5E00029872 /* Copy headers to framework */, 3444602A190CC3320076655A /* Copy Info.plist to framework */, 344077C41BA7544F00037486 /* Set Git SHA on Framework */, ); dependencies = ( ); name = "Cedar-iOS StaticFramework"; productName = "Cedar-iOS"; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 1F45A3CE180E4796003C1E36 /* SpecBundleApplicationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96D34483144A845100352C4A /* SpecBundleApplicationTests.mm */; }; 1F45A3D0180E4796003C1E36 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 1F45A3D1180E4796003C1E36 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; 1F45A3D4180E4796003C1E36 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; 1F45A3D5180E4796003C1E36 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 1F45A3E3180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F45A3E2180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m */; }; 1F47B9A8186D69CD005A8CE1 /* CDROTestReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */; }; 1F483E32187D39D000521F81 /* CDROTestNamer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F483E30187D39D000521F81 /* CDROTestNamer.h */; }; 1F483E33187D39D000521F81 /* CDROTestNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F483E31187D39D000521F81 /* CDROTestNamer.m */; }; 1F483E34187D3CD200521F81 /* CDROTestNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F483E31187D39D000521F81 /* CDROTestNamer.m */; }; 1F882AAA180F9B6300533238 /* BeNil_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 1F882AAC180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 1FDCD5601821D3BB00B511DB /* BeNil_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 1FDCD5611821D3BF00B511DB /* BeSameInstanceAs_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 1FE15C1B1869091900207F0C /* CDRReportDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FE15C191869091900207F0C /* CDRReportDispatcher.h */; }; 1FE15C1D1869091900207F0C /* CDRReportDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */; }; 1FE15C201869091900207F0C /* CDRReportDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */; }; 1FF3591117B6094A00096517 /* CDRExample.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FCC11DC27B800029872 /* CDRExample.h */; }; 1FF3591217B6094A00096517 /* CDRExampleGroup.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */; }; 1FF4497D18A0B37A00AF94B0 /* AnyArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */; }; 1FF4497E18A0B37A00AF94B0 /* AnyArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */; }; 1FF449B118A0C03800AF94B0 /* CDRBufferedDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */; }; 1FF449B218A0C03900AF94B0 /* CDRBufferedDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */; }; 1FF449B518A0C24400AF94B0 /* CDRBufferedDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2234907D18009DA6001C8E8D /* CDRHooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2234907F18009DAD001C8E8D /* CDRHooks.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; }; 228F3FA717E3ECD10000C8AF /* CDRSpyiOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */; }; 22B6A22715B7ACF800960ADE /* InvocationMatcher.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; }; 3414776E191406E700CBA385 /* ComparatorsContainerConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3414776F191406FC00CBA385 /* ComparatorsContainerConvenience.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; }; 34147770191408C900CBA385 /* AnInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 341477711914090000CBA385 /* AnInstanceOf.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; }; 34157D0C1B755DE0007AD1BA /* CDRDefaultReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */; }; 34157D0D1B755DFB007AD1BA /* CDRJUnitXMLReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */; }; 34157D0E1B755E09007AD1BA /* CDROTestReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */; }; 34157D101B755E21007AD1BA /* CDRTeamCityReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; }; 34157D111B755E40007AD1BA /* CDRBufferedDefaultReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */; }; 342FB2C51BC326100090E253 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 342FB2C71BC328320090E253 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 342FB2C61BC328320090E253 /* ApplicationServices.framework */; }; 34322B091BA740B900D0CFBD /* CDRXCTestObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */; }; 34322B0A1BA740B900D0CFBD /* CDRXCTestObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */; }; 34322B0B1BA742B400D0CFBD /* CDRPrivateFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */; }; 34322B0C1BA7471B00D0CFBD /* TestObservationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34757E211BA466050047BC8D /* TestObservationHelper.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 343FAFEA190FDAEC0085AFEC /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; 343FAFEB190FDAEC0085AFEC /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; 345B1E891C31D495009BB77D /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */; }; 345B1E8C1C31D4B4009BB77D /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */; }; 345B1E8F1C31DA6E009BB77D /* XCTAssertSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345B1E8D1C31DA2B009BB77D /* XCTAssertSpec.swift */; }; 345B1E911C31DA70009BB77D /* XCTAssertSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345B1E8D1C31DA2B009BB77D /* XCTAssertSpec.swift */; }; 345B1E921C31E644009BB77D /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; 346261E71B995422002CAEBD /* CDRSpyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */; }; 346261E81B995422002CAEBD /* CedarDoubleImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */; }; 346261E91B995422002CAEBD /* NSInvocation+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */; }; 346261EA1B995422002CAEBD /* NSMethodSignature+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */; }; 346261EB1B995422002CAEBD /* CDROTestNamer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F483E30187D39D000521F81 /* CDROTestNamer.h */; }; 346261EC1B995422002CAEBD /* CDRSlowTestStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */; }; 346261ED1B995422002CAEBD /* CDRReportDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FE15C191869091900207F0C /* CDRReportDispatcher.h */; }; 346261EE1B995422002CAEBD /* CDRBlockHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */; }; 346261EF1B995422002CAEBD /* CDRNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */; }; 346261F11B995422002CAEBD /* CDRPrivateFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */; }; 346261F21B995422002CAEBD /* CDRRuntimeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */; }; 346261F31B995422002CAEBD /* CDRSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */; }; 346261F41B995422002CAEBD /* CDRTypeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */; }; 346261F51B995426002CAEBD /* CDRXCTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */; }; 346261F71B995426002CAEBD /* CDRXCTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */; }; 346261F81B995426002CAEBD /* NSInvocation+CDRXExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */; }; 346261F91B995445002CAEBD /* Argument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136015D1425C003AAB9C /* Argument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FA1B995445002CAEBD /* ValueArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136315D14274003AAB9C /* ValueArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FB1B995445002CAEBD /* AnyInstanceArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FC1B995445002CAEBD /* ReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136615D142E3003AAB9C /* ReturnValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FD1B995445002CAEBD /* AnyArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136915D1439B003AAB9C /* AnyArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FE1B995445002CAEBD /* AnyInstanceOfClassArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346261FF1B995445002CAEBD /* AnyInstanceConformingToProtocolArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262001B99544D002CAEBD /* CDRProtocolFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74902E15B45E80008EA127 /* CDRProtocolFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262011B99544D002CAEBD /* CedarDoubles.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC8714C4DBA70016652A /* CedarDoubles.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262021B99544D002CAEBD /* CDRSpy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC9814C4DD440016652A /* CDRSpy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262031B99544D002CAEBD /* CDRClassFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA67915AB72DA00617E1A /* CDRClassFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262041B99544D002CAEBD /* HaveReceived.h in Headers */ = {isa = PBXBuildFile; fileRef = 6639A78014C50D3000B564B7 /* HaveReceived.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262051B99544D002CAEBD /* CedarDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA68815AC728A00617E1A /* CedarDouble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262061B99544D002CAEBD /* RejectedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A945D1880792E008566F5 /* RejectedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262071B99544D002CAEBD /* StubbedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6D115AE082500617E1A /* StubbedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262081B99544D002CAEBD /* InvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262091B99544D002CAEBD /* CDRFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74907315B488BE008EA127 /* CDRFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620A1B99546C002CAEBD /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFB13ECC21E00786282 /* Base.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620B1B99546C002CAEBD /* BeCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFC13ECC21E00786282 /* BeCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620C1B99546C002CAEBD /* BeFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A9457187F7D8F008566F5 /* BeFalsy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620D1B99546C002CAEBD /* BeGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620E1B99546C002CAEBD /* BeGTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF3300B145B4F75002F93BB /* BeGTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462620F1B99546C002CAEBD /* BeInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262101B99546C002CAEBD /* BeLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33016145B6222002F93BB /* BeLessThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262111B99546C002CAEBD /* BeLTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33020145B69DE002F93BB /* BeLTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262121B99546C002CAEBD /* BeNil.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFE13ECC21E00786282 /* BeNil.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262131B99546C002CAEBD /* BeSameInstanceAs.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262141B99546C002CAEBD /* BeTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300013ECC21E00786282 /* BeTruthy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262151B99546C002CAEBD /* ConformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262161B99546C002CAEBD /* Equal.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300113ECC21E00786282 /* Equal.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262171B99546C002CAEBD /* Exist.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0721E2187518FD0031CC42 /* Exist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262181B99546C002CAEBD /* RaiseException.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB45A901496C8D800845D09 /* RaiseException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262191B99546C002CAEBD /* RespondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = CA17998C17F89C4B00C38060 /* RespondTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621A1B995473002CAEBD /* BeEmpty.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7301013ECC25000786282 /* BeEmpty.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621B1B995473002CAEBD /* Contain.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7FA13F4601400C8872C /* Contain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621C1B995473002CAEBD /* AnInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621D1B99548A002CAEBD /* StringifiersBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303813ECCB7B00786282 /* StringifiersBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621E1B99548A002CAEBD /* StringifiersContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303913ECCB7B00786282 /* StringifiersContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462621F1B995491002CAEBD /* ComparatorsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D213F45BE500C8872C /* ComparatorsBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262201B995491002CAEBD /* ComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262211B995491002CAEBD /* CompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF3145A2E91002F93BB /* CompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262221B995491002CAEBD /* CompareGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262231B995491002CAEBD /* ComparatorsContainerConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262241B995491002CAEBD /* CompareCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462622B1B9954A8002CAEBD /* ActualValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF58413E9E87E00029396 /* ActualValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462622C1B9954A8002CAEBD /* CedarMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462622D1B9954A8002CAEBD /* CedarComparators.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7713EC730700786282 /* CedarComparators.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462622E1B9954A8002CAEBD /* CedarStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7A13EC734000786282 /* CedarStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262301B9954A8002CAEBD /* ShouldSyntax.h in Headers */ = {isa = PBXBuildFile; fileRef = AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262311B9954B8002CAEBD /* CDRColorizedReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262321B9954B8002CAEBD /* CDRDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262331B9954B8002CAEBD /* CDRExampleReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262341B9954B8002CAEBD /* CDRJUnitXMLReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262351B9954B8002CAEBD /* CDROTestReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262361B9954B8002CAEBD /* CDRTeamCityReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262371B9954B8002CAEBD /* CDRBufferedDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262381B9954C1002CAEBD /* CDRExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCC11DC27B800029872 /* CDRExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262391B9954C1002CAEBD /* CDRExampleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623A1B9954C1002CAEBD /* CDRExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623B1B9954C1002CAEBD /* CDRExampleParent.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623C1B9954C1002CAEBD /* CDRFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD111DC27B800029872 /* CDRFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623D1B9954C1002CAEBD /* CDRHooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623E1B9954C1002CAEBD /* CDRSharedExampleGroupPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3462623F1B9954C1002CAEBD /* CDRSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD211DC27B800029872 /* CDRSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262401B9954C1002CAEBD /* CDRSpecFailure.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262411B9954C1002CAEBD /* CDRSpecHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262421B9954C1002CAEBD /* CDRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262431B9954C1002CAEBD /* Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD311DC27B800029872 /* Cedar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262441B9954E0002CAEBD /* CDRProtocolFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74906E15B48690008EA127 /* CDRProtocolFake.mm */; }; 346262451B9954E0002CAEBD /* CDRSpy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6628FC9B14C4DEC50016652A /* CDRSpy.mm */; }; 346262461B9954E0002CAEBD /* CDRClassFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */; }; 346262471B9954E0002CAEBD /* CedarDoubleImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */; }; 346262481B9954E0002CAEBD /* CDRFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74907015B486CD008EA127 /* CDRFake.mm */; }; 346262491B9954E0002CAEBD /* CedarDouble.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */; }; 3462624A1B9954E0002CAEBD /* RejectedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A946018807DA6008566F5 /* RejectedMethod.mm */; }; 3462624B1B9954E0002CAEBD /* StubbedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB1A74115F304A9002E4167 /* StubbedMethod.mm */; }; 3462624C1B9954E0002CAEBD /* InvocationMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7873715F440980058A27B /* InvocationMatcher.mm */; }; 3462624D1B9954E0002CAEBD /* HaveReceived.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7874C15F444A50058A27B /* HaveReceived.mm */; }; 3462624E1B9954E0002CAEBD /* CDRSpyInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */; }; 3462624F1B9954E4002CAEBD /* AnyInstanceArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */; }; 346262501B9954E4002CAEBD /* AnyArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */; }; 346262511B9954E4002CAEBD /* AnyInstanceOfClassArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */; }; 346262521B9954E4002CAEBD /* AnyInstanceConformingToProtocolArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */; }; 346262531B9954EA002CAEBD /* NSInvocation+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */; }; 346262541B9954EA002CAEBD /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; 346262551B99567D002CAEBD /* StringifiersBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02021717452006009A7915 /* StringifiersBase.mm */; }; 346262561B995683002CAEBD /* RaiseException.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE167EF115B216DA005960B9 /* RaiseException.mm */; }; 346262571B995683002CAEBD /* RespondTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17998F17F89C9700C38060 /* RespondTo.mm */; }; 346262581B995683002CAEBD /* ConformTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898AADDDCB0B204C88D1199 /* ConformTo.mm */; }; 346262591B995689002CAEBD /* CDROTestNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F483E31187D39D000521F81 /* CDROTestNamer.m */; }; 3462625A1B995689002CAEBD /* CDRSlowTestStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */; }; 3462625B1B99568F002CAEBD /* CDRColorizedReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */; }; 3462625C1B99568F002CAEBD /* CDRDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */; }; 3462625D1B99568F002CAEBD /* CDRJUnitXMLReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */; }; 3462625E1B99568F002CAEBD /* CDROTestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */; }; 3462625F1B99568F002CAEBD /* CDRReportDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */; }; 346262601B99568F002CAEBD /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; }; 346262611B99568F002CAEBD /* CDRBufferedDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */; }; 346262621B995696002CAEBD /* CDRSpec+XCTestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */; }; 346262631B995696002CAEBD /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; 346262641B995696002CAEBD /* CDRXCTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */; }; 346262651B995696002CAEBD /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; 346262661B995696002CAEBD /* NSInvocation+CDRXExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */; }; 346262671B99569B002CAEBD /* CDRExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC511DC27B800029872 /* CDRExample.m */; }; 346262681B99569B002CAEBD /* CDRExampleBase.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC611DC27B800029872 /* CDRExampleBase.m */; }; 346262691B99569B002CAEBD /* CDRExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */; }; 3462626A1B99569B002CAEBD /* CDRFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC811DC27B800029872 /* CDRFunctions.m */; }; 3462626B1B99569B002CAEBD /* CDRTestBundleRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */; }; 3462626C1B99569B002CAEBD /* CDRRuntimeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */; }; 3462626D1B99569B002CAEBD /* CDRSharedExampleGroupPool.m in Sources */ = {isa = PBXBuildFile; fileRef = AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */; }; 3462626E1B99569B002CAEBD /* CDRSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC911DC27B800029872 /* CDRSpec.m */; }; 3462626F1B99569B002CAEBD /* CDRSpecFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEF360619DE21DB00794484 /* CDRSpecFailure.m */; }; 346262701B99569B002CAEBD /* CDRSpecHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */; }; 346262711B99569B002CAEBD /* CDRSymbolicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */; }; 346262721B99569B002CAEBD /* CDRTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */; }; 346262731B99569B002CAEBD /* CDRNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */; }; 346262741B99BE9F002CAEBD /* UIGeometryCompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262751B99BE9F002CAEBD /* UIGeometryStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346262851B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 346262841B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 3462628E1B99C1DC002CAEBD /* ExtensionDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3462628D1B99C1DC002CAEBD /* ExtensionDelegate.mm */; }; 346262A01B99D0DD002CAEBD /* Cedar.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 346261DF1B995239002CAEBD /* Cedar.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 34640DA71B6964F90083EB01 /* CDRBlockHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */; }; 34640DA81B6964FE0083EB01 /* CDRTypeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */; }; 34640DA91B6965060083EB01 /* CDRNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */; }; 34681C2C18FE451E009D38AC /* CDRTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */; }; 34681C2E18FE4884009D38AC /* CDRTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */; }; 34681C3018FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; 34681C3118FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; 346D1A971BBB37F400BECD4B /* SpecBundleApplicationTestsWithXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F45A3E2180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m */; }; 346D1A991BBB3DDD00BECD4B /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FED11DC27B800029872 /* main.mm */; }; 346D1A9A1BBB3DDE00BECD4B /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FED11DC27B800029872 /* main.mm */; }; 346D1A9B1BBB404800BECD4B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; 346D1A9C1BBB405600BECD4B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; 346D1A9E1BBB408E00BECD4B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 346D1A9F1BBB408F00BECD4B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 346D1AA81BBC406700BECD4B /* libCedar.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE222911DC2B0600029872 /* libCedar.a */; }; 346D1AAA1BBC41FE00BECD4B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 346D1AA91BBC41FE00BECD4B /* Foundation.framework */; }; 346D1AAB1BBC43E600BECD4B /* CDROTestReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */; }; 346D1AAD1BBC46B600BECD4B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 346D1AAC1BBC46B600BECD4B /* QuartzCore.framework */; }; 346F646A1B82D01700F64156 /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346F646E1B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; 346F646F1B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; 346F64701B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; 346F64741B82D90900F64156 /* BlockMatcher.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; }; 346F64751B82D90C00F64156 /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34757E261BA4A48E0047BC8D /* TestObservationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34757E211BA466050047BC8D /* TestObservationHelper.m */; }; 34777EB71B99451200A69FCF /* CDRPrivateFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */; }; 34852D151BBE35FF0072D249 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B5FA04144A81A8000A6A5D /* main.m */; }; 34852D161BBE35FF0072D249 /* iOSHostAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B5FA07144A81A8000A6A5D /* iOSHostAppDelegate.m */; }; 34852D181BBE35FF0072D249 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; 34852D191BBE35FF0072D249 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 34852D1D1BBE35FF0072D249 /* Cedar-watchOS Specs.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 346262781B99C1DB002CAEBD /* Cedar-watchOS Specs.app */; }; 34852D261BBE38EE0072D249 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 34852D251BBE38EE0072D249 /* Default-568h@2x.png */; }; 3492DA971BA670C10032B35A /* CDRXCTestFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */; }; 3492DA981BA670C10032B35A /* CDRXCTestFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */; }; 3492DA991BA670C10032B35A /* CDRXCTestFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */; }; 3492DA9B1BA672AB0032B35A /* CDRXCTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */; }; 3492DA9C1BA672AD0032B35A /* CDRXCTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */; }; 3492DA9F1BA6F9E70032B35A /* CDRSpecRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */; }; 3492DAA11BA6F9E70032B35A /* CDRSpecRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */; }; 3492DAA21BA6F9E70032B35A /* CDRSpecRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */; }; 3492DAA31BA6F9E70032B35A /* CDRSpecRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */; }; 3492DAA41BA6F9E70032B35A /* CDRSpecRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */; }; 34A848581B9A4A0500396A09 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34A848571B9A4A0500396A09 /* UIKit.framework */; }; 34A848591B9A4A2E00396A09 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 34A848551B9A491E00396A09 /* Interface.storyboard */; }; 34ADD2E01921F18100B057AC /* AnyInstanceOfClassArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */; }; 34ADD2E11921F18100B057AC /* AnyInstanceOfClassArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */; }; 34ADD2E71921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */; }; 34ADD2E81921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */; }; 34ADD2EB19220F7400B057AC /* AnyInstanceOfClassArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34ADD2EC19220F7400B057AC /* AnyInstanceConformingToProtocolArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34ADD2ED19220F9300B057AC /* AnyInstanceOfClassArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */; }; 34ADD2EE19220F9300B057AC /* AnyInstanceConformingToProtocolArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; }; 34ADE41818F23C8E00BD1E99 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; 34ADE41918F23E6B00BD1E99 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; 34AF814E1C53339300DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; }; 34AF814F1C53A06500DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34AF81501C53A06600DB5249 /* TestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AF814D1C53339300DB5249 /* TestReporter.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34C95F501C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F511C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F521C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F531C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34C95F541C2DD7B30055F089 /* CDRNullabilityCompat.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */; }; 34C95F551C2E57A90055F089 /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */; }; 34C95F561C2F16900055F089 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; }; 34D1819C1BC7F0E60087EC0D /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D1819D1BC7F0E70087EC0D /* BlockMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 346F64681B82D01700F64156 /* BlockMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D1819E1BC7F0FD0087EC0D /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; 34D1819F1BC7F0FD0087EC0D /* BlockMatcher_ARCSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D181A01BC7F0FF0087EC0D /* BlockMatcherSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */; }; 34D181A11BC7F0FF0087EC0D /* BlockMatcher_ARCSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D4B5C318F3AE0400FB2C3B /* UIKitContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */; }; 34D7C3C01BB970DF00E8E523 /* CDRXCTestFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */; }; 34D7C3C11BB970F100E8E523 /* CDRSpecRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */; }; 34D7C3C21BB9710300E8E523 /* CDRXCTestObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */; }; 34D7C3C31BB9710800E8E523 /* CDRXCTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */; }; 34D7C3C41BB9710F00E8E523 /* CDRSpecRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */; }; 34D7C3D21BB9B4D600E8E523 /* AnyInstanceArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */; }; 34D7C3D31BB9B4D600E8E523 /* AnyArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */; }; 34D7C3D41BB9B4D600E8E523 /* AnyInstanceOfClassArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */; }; 34D7C3D51BB9B4D600E8E523 /* AnyInstanceConformingToProtocolArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */; }; 34D7C3D61BB9B4D600E8E523 /* CDRProtocolFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74906E15B48690008EA127 /* CDRProtocolFake.mm */; }; 34D7C3D71BB9B4D600E8E523 /* CDRSpy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6628FC9B14C4DEC50016652A /* CDRSpy.mm */; }; 34D7C3D81BB9B4D600E8E523 /* CDRClassFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */; }; 34D7C3D91BB9B4D600E8E523 /* CedarDoubleImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */; }; 34D7C3DA1BB9B4D600E8E523 /* CDRFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74907015B486CD008EA127 /* CDRFake.mm */; }; 34D7C3DB1BB9B4D600E8E523 /* CedarDouble.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */; }; 34D7C3DC1BB9B4D600E8E523 /* RejectedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A946018807DA6008566F5 /* RejectedMethod.mm */; }; 34D7C3DD1BB9B4D600E8E523 /* StubbedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB1A74115F304A9002E4167 /* StubbedMethod.mm */; }; 34D7C3DE1BB9B4D600E8E523 /* InvocationMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7873715F440980058A27B /* InvocationMatcher.mm */; }; 34D7C3DF1BB9B4D600E8E523 /* HaveReceived.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7874C15F444A50058A27B /* HaveReceived.mm */; }; 34D7C3E01BB9B4D600E8E523 /* CDRSpyInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */; }; 34D7C3E11BB9B4DD00E8E523 /* NSInvocation+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */; }; 34D7C3E21BB9B4DD00E8E523 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; 34D7C3E31BB9B51100E8E523 /* NSBundle+MainBundleHijack.m in Sources */ = {isa = PBXBuildFile; fileRef = 960118BB1434867E00825FFF /* NSBundle+MainBundleHijack.m */; }; 34D7C3E41BB9B51100E8E523 /* CedarApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */; }; 34D7C3E51BB9B51600E8E523 /* StringifiersBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02021717452006009A7915 /* StringifiersBase.mm */; }; 34D7C3E61BB9B51900E8E523 /* RaiseException.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE167EF115B216DA005960B9 /* RaiseException.mm */; }; 34D7C3E71BB9B51900E8E523 /* RespondTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17998F17F89C9700C38060 /* RespondTo.mm */; }; 34D7C3E81BB9B51900E8E523 /* ConformTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898AADDDCB0B204C88D1199 /* ConformTo.mm */; }; 34D7C3E91BB9B51E00E8E523 /* CDROTestNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F483E31187D39D000521F81 /* CDROTestNamer.m */; }; 34D7C3EA1BB9B51E00E8E523 /* CDRSlowTestStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */; }; 34D7C3EB1BB9B52200E8E523 /* CDRColorizedReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */; }; 34D7C3EC1BB9B52200E8E523 /* CDRDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */; }; 34D7C3ED1BB9B52200E8E523 /* CDRJUnitXMLReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */; }; 34D7C3EE1BB9B52200E8E523 /* CDROTestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */; }; 34D7C3EF1BB9B52200E8E523 /* CDRReportDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */; }; 34D7C3F01BB9B52200E8E523 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; }; 34D7C3F11BB9B52200E8E523 /* CDRBufferedDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */; }; 34D7C3F21BB9B52700E8E523 /* CDRSpec+XCTestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */; }; 34D7C3F31BB9B52700E8E523 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; 34D7C3F41BB9B52700E8E523 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; 34D7C3F51BB9B52700E8E523 /* CDRXCTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */; }; 34D7C3F61BB9B52700E8E523 /* NSInvocation+CDRXExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */; }; 34D7C3F71BB9B52700E8E523 /* CDRXCTestFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */; }; 34D7C3F81BB9B52E00E8E523 /* CDRExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC511DC27B800029872 /* CDRExample.m */; }; 34D7C3F91BB9B52E00E8E523 /* CDRExampleBase.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC611DC27B800029872 /* CDRExampleBase.m */; }; 34D7C3FA1BB9B52E00E8E523 /* CDRExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */; }; 34D7C3FB1BB9B52E00E8E523 /* CDRFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC811DC27B800029872 /* CDRFunctions.m */; }; 34D7C3FC1BB9B52E00E8E523 /* CDRTestBundleRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */; }; 34D7C3FD1BB9B52E00E8E523 /* CDRRuntimeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */; }; 34D7C3FE1BB9B52E00E8E523 /* CDRSharedExampleGroupPool.m in Sources */ = {isa = PBXBuildFile; fileRef = AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */; }; 34D7C3FF1BB9B52E00E8E523 /* CDRSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC911DC27B800029872 /* CDRSpec.m */; }; 34D7C4001BB9B52E00E8E523 /* CDRSpecFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEF360619DE21DB00794484 /* CDRSpecFailure.m */; }; 34D7C4011BB9B52E00E8E523 /* CDRSpecHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */; }; 34D7C4021BB9B52E00E8E523 /* CDRSymbolicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */; }; 34D7C4031BB9B52E00E8E523 /* CDRTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */; }; 34D7C4041BB9B52E00E8E523 /* CDRNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */; }; 34D7C4051BB9B52E00E8E523 /* CDRSpecRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */; }; 34D7C4061BB9B53C00E8E523 /* CDRSpyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */; }; 34D7C4071BB9B53C00E8E523 /* CedarDoubleImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */; }; 34D7C4081BB9B53F00E8E523 /* NSInvocation+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */; }; 34D7C4091BB9B53F00E8E523 /* NSMethodSignature+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */; }; 34D7C40A1BB9B54600E8E523 /* CDROTestNamer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F483E30187D39D000521F81 /* CDROTestNamer.h */; }; 34D7C40B1BB9B54600E8E523 /* CDRSlowTestStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */; }; 34D7C40C1BB9B54A00E8E523 /* CDRReportDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FE15C191869091900207F0C /* CDRReportDispatcher.h */; }; 34D7C40D1BB9B54F00E8E523 /* CDRXCTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */; }; 34D7C40E1BB9B54F00E8E523 /* CDRXCTestObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */; }; 34D7C40F1BB9B54F00E8E523 /* CDRXCTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */; }; 34D7C4101BB9B54F00E8E523 /* CDRXCTestSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */; }; 34D7C4111BB9B54F00E8E523 /* NSInvocation+CDRXExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */; }; 34D7C4121BB9B55500E8E523 /* CDRBlockHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */; }; 34D7C4131BB9B55500E8E523 /* CDRNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */; }; 34D7C4141BB9B55500E8E523 /* CDRPrivateFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */; }; 34D7C4151BB9B55500E8E523 /* CDRRuntimeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */; }; 34D7C4161BB9B55500E8E523 /* CDRSpecRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */; }; 34D7C4171BB9B55500E8E523 /* CDRSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */; }; 34D7C4181BB9B55500E8E523 /* CDRTypeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */; }; 34D7C4191BB9B56D00E8E523 /* Argument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136015D1425C003AAB9C /* Argument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41A1BB9B56D00E8E523 /* ValueArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136315D14274003AAB9C /* ValueArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41B1BB9B56D00E8E523 /* AnyInstanceArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41C1BB9B56D00E8E523 /* ReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136615D142E3003AAB9C /* ReturnValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41D1BB9B56D00E8E523 /* AnyArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136915D1439B003AAB9C /* AnyArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41E1BB9B56D00E8E523 /* AnyInstanceOfClassArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C41F1BB9B56D00E8E523 /* AnyInstanceConformingToProtocolArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4201BB9B59200E8E523 /* CDRProtocolFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74902E15B45E80008EA127 /* CDRProtocolFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4211BB9B59200E8E523 /* CedarDoubles.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC8714C4DBA70016652A /* CedarDoubles.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4221BB9B59200E8E523 /* CDRSpy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC9814C4DD440016652A /* CDRSpy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4231BB9B59200E8E523 /* CDRClassFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA67915AB72DA00617E1A /* CDRClassFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4241BB9B59200E8E523 /* HaveReceived.h in Headers */ = {isa = PBXBuildFile; fileRef = 6639A78014C50D3000B564B7 /* HaveReceived.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4251BB9B59200E8E523 /* CedarDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA68815AC728A00617E1A /* CedarDouble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4261BB9B59200E8E523 /* RejectedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A945D1880792E008566F5 /* RejectedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4271BB9B59200E8E523 /* StubbedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6D115AE082500617E1A /* StubbedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4281BB9B59200E8E523 /* InvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4291BB9B59200E8E523 /* CDRFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74907315B488BE008EA127 /* CDRFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C42C1BB9B5A400E8E523 /* CedarApplicationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDA11DC27B800029872 /* CedarApplicationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C42D1BB9B5A400E8E523 /* Cedar-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FCA014C503530016652A /* Cedar-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C42E1BB9B5B200E8E523 /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFB13ECC21E00786282 /* Base.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C42F1BB9B5B200E8E523 /* BeCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFC13ECC21E00786282 /* BeCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4301BB9B5B200E8E523 /* BeFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A9457187F7D8F008566F5 /* BeFalsy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4311BB9B5B200E8E523 /* BeGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4321BB9B5B200E8E523 /* BeGTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF3300B145B4F75002F93BB /* BeGTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4331BB9B5B200E8E523 /* BeInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4341BB9B5B200E8E523 /* BeLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33016145B6222002F93BB /* BeLessThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4351BB9B5B200E8E523 /* BeLTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33020145B69DE002F93BB /* BeLTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4361BB9B5B200E8E523 /* BeNil.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFE13ECC21E00786282 /* BeNil.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4371BB9B5B200E8E523 /* BeSameInstanceAs.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4381BB9B5B200E8E523 /* BeTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300013ECC21E00786282 /* BeTruthy.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4391BB9B5B200E8E523 /* ConformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43A1BB9B5B200E8E523 /* Equal.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300113ECC21E00786282 /* Equal.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43B1BB9B5B200E8E523 /* Exist.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0721E2187518FD0031CC42 /* Exist.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43C1BB9B5B200E8E523 /* RaiseException.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB45A901496C8D800845D09 /* RaiseException.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43D1BB9B5B200E8E523 /* RespondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = CA17998C17F89C4B00C38060 /* RespondTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43E1BB9B5B900E8E523 /* BeEmpty.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7301013ECC25000786282 /* BeEmpty.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C43F1BB9B5B900E8E523 /* Contain.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7FA13F4601400C8872C /* Contain.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4401BB9B5B900E8E523 /* AnInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4411BB9B5BF00E8E523 /* StringifiersBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303813ECCB7B00786282 /* StringifiersBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4421BB9B5BF00E8E523 /* StringifiersContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303913ECCB7B00786282 /* StringifiersContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4431BB9B5C500E8E523 /* ComparatorsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D213F45BE500C8872C /* ComparatorsBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4441BB9B5C500E8E523 /* ComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4451BB9B5C500E8E523 /* CompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF3145A2E91002F93BB /* CompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4461BB9B5C500E8E523 /* CompareGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4471BB9B5C500E8E523 /* ComparatorsContainerConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4481BB9B5C500E8E523 /* CompareCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4491BB9B5D300E8E523 /* UIKitComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D4B5C418F3B68900FB2C3B /* UIKitComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44A1BB9B5D300E8E523 /* UIGeometryCompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44B1BB9B5D300E8E523 /* UIGeometryStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44C1BB9B5DF00E8E523 /* ActualValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF58413E9E87E00029396 /* ActualValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44D1BB9B5DF00E8E523 /* CedarMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44E1BB9B5DF00E8E523 /* CedarComparators.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7713EC730700786282 /* CedarComparators.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C44F1BB9B5DF00E8E523 /* CedarStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7A13EC734000786282 /* CedarStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4501BB9B5E400E8E523 /* ShouldSyntax.h in Headers */ = {isa = PBXBuildFile; fileRef = AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4511BB9B5E900E8E523 /* CDRColorizedReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4521BB9B5E900E8E523 /* CDRDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4531BB9B5E900E8E523 /* CDRExampleReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4541BB9B5E900E8E523 /* CDRJUnitXMLReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4551BB9B5E900E8E523 /* CDROTestReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4561BB9B5E900E8E523 /* CDRTeamCityReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4571BB9B5E900E8E523 /* CDRBufferedDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4581BB9B5F100E8E523 /* CDRExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCC11DC27B800029872 /* CDRExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4591BB9B5F100E8E523 /* CDRExampleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45A1BB9B5F100E8E523 /* CDRExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45B1BB9B5F100E8E523 /* CDRExampleParent.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45C1BB9B5F100E8E523 /* CDRFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD111DC27B800029872 /* CDRFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45D1BB9B5F100E8E523 /* CDRHooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45E1BB9B5F100E8E523 /* CDRSharedExampleGroupPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C45F1BB9B5F100E8E523 /* CDRSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD211DC27B800029872 /* CDRSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4601BB9B5F100E8E523 /* CDRSpecFailure.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4611BB9B5F100E8E523 /* CDRSpecHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4621BB9B5F100E8E523 /* CDRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4631BB9B5F100E8E523 /* Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD311DC27B800029872 /* Cedar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34D7C4731BB9B79500E8E523 /* edward.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360F19DF27E400794484 /* edward.jpg */; }; 34D7C4741BB9B79500E8E523 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360D19DF24AB00794484 /* image.png */; }; 34D7C4751BB9B79D00E8E523 /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; 34D7C4761BB9B79D00E8E523 /* CDRJUnitXMLReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */; }; 34D7C4771BB9B79D00E8E523 /* CDROTestReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */; }; 34D7C4781BB9B7A500E8E523 /* ARCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AE71E7CB175E958F002A54D5 /* ARCViewController.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4791BB9B7AB00E8E523 /* ArgumentReleaser.m in Sources */ = {isa = PBXBuildFile; fileRef = AE807888183C71950078C608 /* ArgumentReleaser.m */; }; 34D7C47A1BB9B7AD00E8E523 /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; 34D7C47B1BB9B7B000E8E523 /* ObjectWithForwardingTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */; }; 34D7C47C1BB9C5FD00E8E523 /* ObjectWithProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */; }; 34D7C47D1BB9C60100E8E523 /* ObjectWithWeakDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C47E1BB9C60700E8E523 /* ObjectWithCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */; }; 34D7C47F1BB9C60A00E8E523 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; 34D7C4801BB9C60D00E8E523 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; 34D7C4811BB9C61300E8E523 /* GDataXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */; }; 34D7C4821BB9C61700E8E523 /* ExampleWithPublicRunDates.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */; }; 34D7C4831BB9C61A00E8E523 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; 34D7C4841BB9C61E00E8E523 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; 34D7C4851BB9C62400E8E523 /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; 34D7C4861BB9C65700E8E523 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4871BB9C66000E8E523 /* CedarApplicationDelegateSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */; }; 34D7C4881BB9C67100E8E523 /* WeakReferenceCompatibilitySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */; }; 34D7C4891BB9C67400E8E523 /* CDRSpyiOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */; }; 34D7C48A1BB9C67C00E8E523 /* BeCloseToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */; }; 34D7C48B1BB9C67C00E8E523 /* BeFalsySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */; }; 34D7C48C1BB9C67C00E8E523 /* BeGreaterThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */; }; 34D7C48D1BB9C67C00E8E523 /* BeGTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33008145B4E3B002F93BB /* BeGTESpec.mm */; }; 34D7C48E1BB9C67C00E8E523 /* BeInstanceOfSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */; }; 34D7C48F1BB9C67C00E8E523 /* BeLessThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33012145B6188002F93BB /* BeLessThanSpec.mm */; }; 34D7C4901BB9C67C00E8E523 /* BeLTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF3301D145B68D7002F93BB /* BeLTESpec.mm */; }; 34D7C4911BB9C67C00E8E523 /* BeNil_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4921BB9C67C00E8E523 /* BeNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301613ECC4AE00786282 /* BeNilSpec.mm */; }; 34D7C4931BB9C67C00E8E523 /* BeSameInstanceAs_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4941BB9C67C00E8E523 /* BeSameInstanceAsSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */; }; 34D7C4951BB9C67C00E8E523 /* BeTruthySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */; }; 34D7C4961BB9C67C00E8E523 /* ConformToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898A53A07BC580786243CD0 /* ConformToSpec.mm */; }; 34D7C4971BB9C67C00E8E523 /* EqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301913ECC4AE00786282 /* EqualSpec.mm */; }; 34D7C4981BB9C67C00E8E523 /* ExistSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0721DF187513870031CC42 /* ExistSpec.mm */; }; 34D7C4991BB9C67C00E8E523 /* MutableEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */; }; 34D7C49A1BB9C67C00E8E523 /* RaiseExceptionSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */; }; 34D7C49B1BB9C67C00E8E523 /* RespondToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17999217F8A0EE00C38060 /* RespondToSpec.mm */; }; 34D7C49C1BB9C68100E8E523 /* BeEmptySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */; }; 34D7C49D1BB9C68100E8E523 /* ContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE18A80913F4640600C8872C /* ContainSpec.mm */; }; 34D7C49E1BB9C68900E8E523 /* UIKitEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */; }; 34D7C49F1BB9C68900E8E523 /* UIKitContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */; }; 34D7C4A01BB9C68E00E8E523 /* ShouldSyntaxSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */; }; 34D7C4A11BB9C69100E8E523 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; 34D7C4A21BB9C69A00E8E523 /* CDRClassFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */; }; 34D7C4A31BB9C69A00E8E523 /* CDRProtocolFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */; }; 34D7C4A41BB9C69A00E8E523 /* CDRSpySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */; }; 34D7C4A51BB9C69A00E8E523 /* CedarDoubleARCSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4A61BB9C69A00E8E523 /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; 34D7C4A71BB9C69A00E8E523 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; 34D7C4A81BB9C69A00E8E523 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; 34D7C4A91BB9C69A00E8E523 /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; 34D7C4AA1BB9C6C400E8E523 /* CDRSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */; }; 34D7C4AB1BB9C6C400E8E523 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; 34D7C4AC1BB9C6C400E8E523 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; 34D7C4AD1BB9C6C400E8E523 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 34D7C4AE1BB9C6C400E8E523 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; 34D7C4AF1BB9C6C400E8E523 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; 34D7C4B01BB9C6C400E8E523 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 34D7C4B11BB9C6C400E8E523 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; 34D7C4B21BB9C6C700E8E523 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; 34D7C4B31BB9C6C700E8E523 /* CDRNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */; }; 34D7C4B41BB9C75D00E8E523 /* TestObservationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34757E211BA466050047BC8D /* TestObservationHelper.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34D7C4B61BB9CB4B00E8E523 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34D7C3CA1BB9747400E8E523 /* Cedar.framework */; }; 34D7C4B81BB9CB5700E8E523 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 34D7C4B71BB9CB5700E8E523 /* libxml2.tbd */; }; 34DB67491C2B4D6A00206663 /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */; }; 34DB674A1C2B65EA00206663 /* ContainSubset.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8F9C141B795A7C00B956C5 /* ContainSubset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB674B1C2B65EA00206663 /* ContainSubset.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8F9C141B795A7C00B956C5 /* ContainSubset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB674C1C2B65EB00206663 /* ContainSubset.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8F9C141B795A7C00B956C5 /* ContainSubset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB674D1C2B65EC00206663 /* ContainSubset.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8F9C141B795A7C00B956C5 /* ContainSubset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB674E1C2B65EC00206663 /* ContainSubset.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE8F9C141B795A7C00B956C5 /* ContainSubset.h */; }; 34DB67501C2B8C1000206663 /* CedarReporters.h in Headers */ = {isa = PBXBuildFile; fileRef = 34DB674F1C2B8C1000206663 /* CedarReporters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB67511C2B8C1000206663 /* CedarReporters.h in Headers */ = {isa = PBXBuildFile; fileRef = 34DB674F1C2B8C1000206663 /* CedarReporters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB67521C2B8C1000206663 /* CedarReporters.h in Headers */ = {isa = PBXBuildFile; fileRef = 34DB674F1C2B8C1000206663 /* CedarReporters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB67531C2B8C1000206663 /* CedarReporters.h in Headers */ = {isa = PBXBuildFile; fileRef = 34DB674F1C2B8C1000206663 /* CedarReporters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 34DB67541C2B8C1000206663 /* CedarReporters.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34DB674F1C2B8C1000206663 /* CedarReporters.h */; }; 34EBFD0F18FF505F005392AB /* UIKitComparatorsContainer.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 34D4B5C418F3B68900FB2C3B /* UIKitComparatorsContainer.h */; }; 34F3DF7F1A6ABA2E003041DA /* CDRNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */; }; 34F3DF801A6ABA2E003041DA /* CDRNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */; }; 34F3DF821A6ABB21003041DA /* CDRNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */; }; 34F3DF831A6ABB21003041DA /* CDRNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */; }; 34FD462A1B99D13C00257186 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 346261DF1B995239002CAEBD /* Cedar.framework */; }; 34FD462B1B99D1FD00257186 /* edward.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360F19DF27E400794484 /* edward.jpg */; }; 34FD462C1B99D1FD00257186 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360D19DF24AB00794484 /* image.png */; }; 34FD462D1B99D21300257186 /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; 34FD462E1B99D21300257186 /* CDRJUnitXMLReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */; }; 34FD462F1B99D21300257186 /* CDROTestReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */; }; 34FD46311B99D22700257186 /* ArgumentReleaser.m in Sources */ = {isa = PBXBuildFile; fileRef = AE807888183C71950078C608 /* ArgumentReleaser.m */; }; 34FD46321B99D22A00257186 /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; 34FD46331B99D22D00257186 /* ObjectWithForwardingTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */; }; 34FD46341B99D23000257186 /* ObjectWithProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */; }; 34FD46351B99D23300257186 /* ObjectWithWeakDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34FD46361B99D23500257186 /* ObjectWithCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */; }; 34FD46371B99D23800257186 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; 34FD46381B99D23C00257186 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; 34FD46391B99D24400257186 /* GDataXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */; }; 34FD463A1B99D24900257186 /* ExampleWithPublicRunDates.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */; }; 34FD463B1B99D25000257186 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; 34FD463C1B99D25200257186 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; 34FD463D1B99D25600257186 /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; 34FD463F1B99D2B000257186 /* BeCloseToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */; }; 34FD46401B99D2B000257186 /* BeFalsySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */; }; 34FD46411B99D2B000257186 /* BeGreaterThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */; }; 34FD46421B99D2B000257186 /* BeGTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33008145B4E3B002F93BB /* BeGTESpec.mm */; }; 34FD46431B99D2B000257186 /* BeInstanceOfSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */; }; 34FD46441B99D2B000257186 /* BeLessThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33012145B6188002F93BB /* BeLessThanSpec.mm */; }; 34FD46451B99D2B000257186 /* BeLTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF3301D145B68D7002F93BB /* BeLTESpec.mm */; }; 34FD46461B99D2B000257186 /* BeNil_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34FD46471B99D2B000257186 /* BeNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301613ECC4AE00786282 /* BeNilSpec.mm */; }; 34FD46481B99D2B000257186 /* BeSameInstanceAs_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34FD46491B99D2B000257186 /* BeSameInstanceAsSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */; }; 34FD464A1B99D2B000257186 /* BeTruthySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */; }; 34FD464B1B99D2B000257186 /* ConformToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898A53A07BC580786243CD0 /* ConformToSpec.mm */; }; 34FD464C1B99D2B000257186 /* EqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301913ECC4AE00786282 /* EqualSpec.mm */; }; 34FD464D1B99D2B000257186 /* ExistSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0721DF187513870031CC42 /* ExistSpec.mm */; }; 34FD464E1B99D2B000257186 /* MutableEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */; }; 34FD464F1B99D2B000257186 /* RaiseExceptionSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */; }; 34FD46501B99D2B000257186 /* RespondToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17999217F8A0EE00C38060 /* RespondToSpec.mm */; }; 34FD46511B99D2B500257186 /* BeEmptySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */; }; 34FD46521B99D2B500257186 /* ContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE18A80913F4640600C8872C /* ContainSpec.mm */; }; 34FD46531B99D2B900257186 /* UIKitEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */; }; 34FD46541B99D2C100257186 /* ShouldSyntaxSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */; }; 34FD46551B99D2CD00257186 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; 34FD46561B99D2E300257186 /* CDRClassFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */; }; 34FD46571B99D2E300257186 /* CDRProtocolFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */; }; 34FD46581B99D2E300257186 /* CDRSpySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */; }; 34FD46591B99D2E300257186 /* CedarDoubleARCSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; 34FD465A1B99D2E300257186 /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; 34FD465B1B99D2E300257186 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; 34FD465C1B99D2E300257186 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; 34FD465D1B99D2E300257186 /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; 34FD465E1B99D2F200257186 /* CDRSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */; }; 34FD465F1B99D2F200257186 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; 34FD46601B99D2F200257186 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; 34FD46611B99D2F200257186 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 34FD46621B99D2F200257186 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; 34FD46631B99D2F200257186 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; 34FD46641B99D2F200257186 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 34FD46651B99D2F200257186 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; 34FD46661B99D2F900257186 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; 34FD46671B99D2F900257186 /* CDRNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */; }; 34FD466A1B99D43F00257186 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 34FD46681B99D43400257186 /* libxml2.tbd */; }; 42064466139B44EC00C85605 /* CDRTeamCityReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4206446A139B44F600C85605 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; }; 4206446B139B44F600C85605 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; }; 44B9A71E1888660400CBCA1B /* GDataXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */; }; 44B9A71F1888661100CBCA1B /* ExampleWithPublicRunDates.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */; }; 4523F335DBD90BD048BB7397 /* GDataXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */; }; 4523F7CCCA3C9010878941F7 /* ExampleWithPublicRunDates.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */; }; 492951DD1481AAD800FA8916 /* CDRJUnitXMLReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 492951E01481AAFA00FA8916 /* CDRJUnitXMLReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */; }; 492951E11481AAFA00FA8916 /* CDRJUnitXMLReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */; }; 492951E41482FF6300FA8916 /* CDRJUnitXMLReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */; }; 492951E51482FF6300FA8916 /* CDRJUnitXMLReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */; }; 5898A1BAE1D014B764946811 /* ConformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5898A49E3306FFF7A99AC150 /* ConformToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898A53A07BC580786243CD0 /* ConformToSpec.mm */; }; 5898A61AAABFE1802E87E6C3 /* ConformToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898A53A07BC580786243CD0 /* ConformToSpec.mm */; }; 5898A7EC5992B2CC74E399F6 /* RespondToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17999217F8A0EE00C38060 /* RespondToSpec.mm */; }; 5898AC04D63A7FAFFA2A4D5C /* RespondToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17999217F8A0EE00C38060 /* RespondToSpec.mm */; }; 5898ACDB8101DA643EDCCD5B /* ConformTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898AADDDCB0B204C88D1199 /* ConformTo.mm */; }; 5898AF335BC09A1CD5B011C6 /* ConformTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898AADDDCB0B204C88D1199 /* ConformTo.mm */; }; 6628FC8914C4DBA70016652A /* CedarDoubles.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 6628FC8714C4DBA70016652A /* CedarDoubles.h */; }; 6628FC9A14C4DD440016652A /* CDRSpy.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 6628FC9814C4DD440016652A /* CDRSpy.h */; }; 6628FC9C14C4DEC50016652A /* CDRSpy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6628FC9B14C4DEC50016652A /* CDRSpy.mm */; }; 6628FCA114C503530016652A /* Cedar-iOS.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 6628FCA014C503530016652A /* Cedar-iOS.h */; }; 6639A77F14C50D0100B564B7 /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; 6639A78214C50D3000B564B7 /* HaveReceived.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 6639A78014C50D3000B564B7 /* HaveReceived.h */; }; 6639A78714C540CC00B564B7 /* CDRSpy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6628FC9B14C4DEC50016652A /* CDRSpy.mm */; }; 66F00B5214C4D97C00146D88 /* CDRSpySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */; }; 960118BC1434867E00825FFF /* NSBundle+MainBundleHijack.m in Sources */ = {isa = PBXBuildFile; fileRef = 960118BB1434867E00825FFF /* NSBundle+MainBundleHijack.m */; }; 966E74ED145A6CA0002E8D49 /* ShouldSyntaxSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */; }; 966E74EE145A6CA0002E8D49 /* ShouldSyntaxSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */; }; 9672F0A71615C1C10012ED58 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 9672F0A91615C3F40012ED58 /* CDRSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */; }; 9672F0AA1615C3F40012ED58 /* CDRSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */; }; 969B6F84160C61E000C7C792 /* CDRSymbolicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */; }; 969B6F86160C678400C7C792 /* CDRSymbolicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */; }; 969B6F96160F1FEC00C7C792 /* CDRSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */; }; 96A07F0413F276640021974D /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE1FB611DC271300029872 /* Cedar.framework */; }; 96A07F0B13F276B10021974D /* FocusedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F0A13F276B10021974D /* FocusedSpec.m */; }; 96A07F0F13F27F2F0021974D /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F0E13F27F2F0021974D /* main.mm */; }; 96A07F1113F283E40021974D /* FocusedSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F1013F283E40021974D /* FocusedSpec2.m */; }; 96B5918F1630F5840068EA5E /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 96B591911630F5B10068EA5E /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; 96B5F9FC144A81A7000A6A5D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; 96B5FA05144A81A8000A6A5D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B5FA04144A81A8000A6A5D /* main.m */; }; 96B5FA08144A81A8000A6A5D /* iOSHostAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B5FA07144A81A8000A6A5D /* iOSHostAppDelegate.m */; }; 96C95B7E161339160018606B /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; 96D34482144A82DB00352C4A /* DummyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 96D3447F144A82D100352C4A /* DummyView.xib */; }; 96EA1CA8142C6425001A78E0 /* CDROTestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */; }; 96EA1CA9142C6425001A78E0 /* CDROTestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */; }; 96EA1CAA142C6425001A78E0 /* CDRTestBundleRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */; }; 96EA1CAE142C6449001A78E0 /* CDROTestReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 96EA1CBA142C6560001A78E0 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; 96EA1CBB142C6560001A78E0 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; 9D28051918E2321D00887CC4 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; 9D28051A18E2324200887CC4 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; AE02021917452007009A7915 /* StringifiersBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02021717452006009A7915 /* StringifiersBase.mm */; }; AE02021A17452007009A7915 /* StringifiersBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02021717452006009A7915 /* StringifiersBase.mm */; }; AE02E7E6184EABCD00414F19 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */; }; AE02E7E7184EABCD00414F19 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; AE02E813184ECAEE00414F19 /* CDRSpecFailure.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */; }; AE02E814184ECB0F00414F19 /* ShouldSyntax.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */; }; AE02E82A184EF2A300414F19 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AE02E83118526E9F00414F19 /* Cedar-iOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02E83018526E9F00414F19 /* Cedar-iOSSpec.mm */; }; AE03FC0F1B06C37E00013784 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE4864F81B067620005DB302 /* Cedar.framework */; }; AE03FC131B06C3BA00013784 /* Cedar.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = AE4864F81B067620005DB302 /* Cedar.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; AE0695F317A1885A0053E59A /* CedarDoubleARCSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE0695F417A1885A0053E59A /* CedarDoubleARCSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE06D88017AEEE230084D27C /* ObjectWithForwardingTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */; }; AE06D88117AEEE230084D27C /* ObjectWithForwardingTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */; }; AE0721E0187513870031CC42 /* ExistSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0721DF187513870031CC42 /* ExistSpec.mm */; }; AE0721E1187513870031CC42 /* ExistSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0721DF187513870031CC42 /* ExistSpec.mm */; }; AE0721E3187518FD0031CC42 /* Exist.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0721E2187518FD0031CC42 /* Exist.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE0721E4187518FD0031CC42 /* Exist.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE0721E2187518FD0031CC42 /* Exist.h */; }; AE0AF56513E9C0E300029396 /* CedarMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE0AF56C13E9C0FB00029396 /* CedarMatchers.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; }; AE0AF58513E9E87E00029396 /* ActualValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF58413E9E87E00029396 /* ActualValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE0AF58613E9E89D00029396 /* ActualValue.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE0AF58413E9E87E00029396 /* ActualValue.h */; }; AE0BF06F1B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE0BF0701B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE0BF0711B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE0C9D8E19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */; }; AE0C9D8F19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */; }; AE0F354719E7059D00B9F116 /* OSXGeometryCompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354619E7059200B9F116 /* OSXGeometryCompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE0F354B19E7073B00B9F116 /* OSXGeometryEqualSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0F354A19E7073B00B9F116 /* OSXGeometryEqualSpecSpec.mm */; }; AE0F354E19E87D6F00B9F116 /* CompareCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE0F354F19E87D6F00B9F116 /* CompareCloseTo.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */; }; AE0F355019E89BC400B9F116 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; AE167EF215B216DA005960B9 /* RaiseException.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE167EF115B216DA005960B9 /* RaiseException.mm */; }; AE167EF315B216DA005960B9 /* RaiseException.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE167EF115B216DA005960B9 /* RaiseException.mm */; }; AE18A7B813F450A700C8872C /* Base.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72FFB13ECC21E00786282 /* Base.h */; }; AE18A7B913F450A700C8872C /* BeCloseTo.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72FFC13ECC21E00786282 /* BeCloseTo.h */; }; AE18A7BA13F450A700C8872C /* BeInstanceOf.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */; }; AE18A7BB13F450A700C8872C /* BeNil.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72FFE13ECC21E00786282 /* BeNil.h */; }; AE18A7BC13F450A700C8872C /* BeSameInstanceAs.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */; }; AE18A7BD13F450A700C8872C /* BeTruthy.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF7300013ECC21E00786282 /* BeTruthy.h */; }; AE18A7BE13F450A700C8872C /* Equal.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF7300113ECC21E00786282 /* Equal.h */; }; AE18A7BF13F450BD00C8872C /* BeEmpty.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF7301013ECC25000786282 /* BeEmpty.h */; }; AE18A7C013F450BD00C8872C /* StringifiersBase.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF7303813ECCB7B00786282 /* StringifiersBase.h */; }; AE18A7C113F450BD00C8872C /* StringifiersContainer.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF7303913ECCB7B00786282 /* StringifiersContainer.h */; }; AE18A7CA13F453CC00C8872C /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFB13ECC21E00786282 /* Base.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7CB13F453CC00C8872C /* BeCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFC13ECC21E00786282 /* BeCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7CC13F453CC00C8872C /* BeInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7CD13F453CC00C8872C /* BeNil.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFE13ECC21E00786282 /* BeNil.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7CE13F453CC00C8872C /* BeSameInstanceAs.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7CF13F453CC00C8872C /* BeTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300013ECC21E00786282 /* BeTruthy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7D013F453CC00C8872C /* Equal.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300113ECC21E00786282 /* Equal.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7D313F45BE500C8872C /* ComparatorsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D213F45BE500C8872C /* ComparatorsBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7D413F45BE500C8872C /* ComparatorsBase.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE18A7D213F45BE500C8872C /* ComparatorsBase.h */; }; AE18A7D613F45BFC00C8872C /* ComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7D713F45BFC00C8872C /* ComparatorsContainer.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */; }; AE18A7FB13F4601400C8872C /* Contain.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7FA13F4601400C8872C /* Contain.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE18A7FC13F4601400C8872C /* Contain.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE18A7FA13F4601400C8872C /* Contain.h */; }; AE18A80A13F4640600C8872C /* ContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE18A80913F4640600C8872C /* ContainSpec.mm */; }; AE18A80B13F4640600C8872C /* ContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE18A80913F4640600C8872C /* ContainSpec.mm */; }; AE19375A1B1AC149008C8CD8 /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; AE19375D1B1AC22D008C8CD8 /* CDRClassFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */; }; AE19375E1B1AC22D008C8CD8 /* CDRProtocolFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */; }; AE19375F1B1AC22D008C8CD8 /* CDRSpySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */; }; AE1937601B1AC22D008C8CD8 /* CedarDoubleARCSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE1937611B1AC22D008C8CD8 /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; AE1937621B1AC22D008C8CD8 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; AE1937631B1AC22D008C8CD8 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; AE1937641B1AC22D008C8CD8 /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; AE1937651B1AC22D008C8CD8 /* CDRSpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */; }; AE1937661B1AC22D008C8CD8 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AE1937671B1AC22D008C8CD8 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AE1937681B1AC22D008C8CD8 /* CDRSymbolicatorSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */; }; AE1937691B1AC22D008C8CD8 /* CDRSpecFailureSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */; }; AE19376A1B1AC22D008C8CD8 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AE19376B1B1AC22D008C8CD8 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; AE19376C1B1AC22D008C8CD8 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AE19376E1B1AC22D008C8CD8 /* CDRTypeUtilitiesSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */; }; AE19376F1B1AC22D008C8CD8 /* CDRNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */; }; AE1937701B1AC3DC008C8CD8 /* ARCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AE71E7CB175E958F002A54D5 /* ARCViewController.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE1937711B1AC3DC008C8CD8 /* ArgumentReleaser.m in Sources */ = {isa = PBXBuildFile; fileRef = AE807888183C71950078C608 /* ArgumentReleaser.m */; }; AE1937721B1AC3DC008C8CD8 /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; AE1937731B1AC3DC008C8CD8 /* ObjectWithForwardingTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */; }; AE1937741B1AC3DC008C8CD8 /* ObjectWithProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */; }; AE1937751B1AC3DC008C8CD8 /* ObjectWithWeakDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE1937761B1AC3DC008C8CD8 /* ObjectWithCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */; }; AE1937771B1AC3DC008C8CD8 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; AE1937781B1AC3DC008C8CD8 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; AE19377A1B1AC3DC008C8CD8 /* ObjectWithValueEquality.m in Sources */ = {isa = PBXBuildFile; fileRef = 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */; }; AE19377B1B1AC3DC008C8CD8 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; AE19377C1B1AC3DC008C8CD8 /* DeallocNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */; }; AE1937811B1AC4AC008C8CD8 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; AE1937831B1AC90A008C8CD8 /* CedarApplicationDelegateSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */; }; AE1937841B1AC90F008C8CD8 /* WeakReferenceCompatibilitySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */; }; AE1937851B1AC919008C8CD8 /* CDRSpyiOSSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */; }; AE1937861B1AC94D008C8CD8 /* BeCloseToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */; }; AE1937871B1AC94D008C8CD8 /* BeFalsySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */; }; AE1937881B1AC94D008C8CD8 /* BeGreaterThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */; }; AE1937891B1AC94D008C8CD8 /* BeGTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33008145B4E3B002F93BB /* BeGTESpec.mm */; }; AE19378A1B1AC94D008C8CD8 /* BeInstanceOfSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */; }; AE19378B1B1AC94D008C8CD8 /* BeLessThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33012145B6188002F93BB /* BeLessThanSpec.mm */; }; AE19378C1B1AC94D008C8CD8 /* BeLTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF3301D145B68D7002F93BB /* BeLTESpec.mm */; }; AE19378D1B1AC94D008C8CD8 /* BeNil_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE19378E1B1AC94D008C8CD8 /* BeNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301613ECC4AE00786282 /* BeNilSpec.mm */; }; AE19378F1B1AC94D008C8CD8 /* BeSameInstanceAs_ARCSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE1937901B1AC94D008C8CD8 /* BeSameInstanceAsSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */; }; AE1937911B1AC94D008C8CD8 /* BeTruthySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */; }; AE1937921B1AC94D008C8CD8 /* ConformToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898A53A07BC580786243CD0 /* ConformToSpec.mm */; }; AE1937931B1AC94D008C8CD8 /* EqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301913ECC4AE00786282 /* EqualSpec.mm */; }; AE1937941B1AC94D008C8CD8 /* ExistSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0721DF187513870031CC42 /* ExistSpec.mm */; }; AE1937951B1AC94D008C8CD8 /* MutableEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */; }; AE1937961B1AC94D008C8CD8 /* RaiseExceptionSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */; }; AE1937971B1AC94D008C8CD8 /* RespondToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17999217F8A0EE00C38060 /* RespondToSpec.mm */; }; AE1937981B1AC94D008C8CD8 /* BeEmptySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */; }; AE1937991B1AC94D008C8CD8 /* ContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE18A80913F4640600C8872C /* ContainSpec.mm */; }; AE19379A1B1AC94D008C8CD8 /* UIKitEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */; }; AE19379B1B1AC94D008C8CD8 /* UIKitContainSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */; }; AE19379C1B1AC94D008C8CD8 /* ShouldSyntaxSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */; }; AE19379E1B1ACAFB008C8CD8 /* CDRJUnitXMLReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */; }; AE19379F1B1ACAFB008C8CD8 /* CDROTestReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */; }; AE1937A21B1ACC26008C8CD8 /* ExampleWithPublicRunDates.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */; }; AE1937A31B1ACC2E008C8CD8 /* GDataXMLNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */; }; AE248F9D19DCD52500092C14 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AE248F9C19DCD52500092C14 /* main.m */; }; AE248FB819DCD54600092C14 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE1FB611DC271300029872 /* Cedar.framework */; }; AE31A29F19C0F23F00C438C1 /* CDRXCTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */; }; AE31A2A119C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; AE31A2A219C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; AE34722819C11872005CA6F1 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AE34722A19C118C9005CA6F1 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AE34722F19C124CE005CA6F1 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AE34723019C124CE005CA6F1 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AE34723419C124D6005CA6F1 /* ObjCHeadersSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */; }; AE34723719C12534005CA6F1 /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; AE34723919C12588005CA6F1 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; AE34723D19C22547005CA6F1 /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; AE34724619C225A1005CA6F1 /* CDRXCTestSuiteSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE34724B19C37ECF005CA6F1 /* CDRXCTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */; }; AE34724D19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; AE34724E19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; AE36AC6515B5CA6E00EB6C51 /* CedarDouble.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */; }; AE36AC6615B5CA6E00EB6C51 /* CedarDouble.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */; }; AE3E8F39184FEEE900633740 /* ObjectWithCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */; }; AE3E8F3A184FEEEB00633740 /* ObjectWithCollections.m in Sources */ = {isa = PBXBuildFile; fileRef = AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */; }; AE4865121B06769B005DB302 /* NSMethodSignature+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */; }; AE48651D1B06769B005DB302 /* CDRSpyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */; }; AE4865231B06769B005DB302 /* CedarDoubleImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */; }; AE4865531B06769D005DB302 /* CDRReportDispatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FE15C191869091900207F0C /* CDRReportDispatcher.h */; }; AE4865551B06769D005DB302 /* CDRBufferedDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865661B06769F005DB302 /* CDRRuntimeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */; }; AE4865681B06769F005DB302 /* CDRXCTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */; }; AE4865691B06769F005DB302 /* CDRXCTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */; }; AE48656A1B06769F005DB302 /* NSInvocation+CDRXExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */; }; AE48656B1B06769F005DB302 /* CDROTestNamer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F483E30187D39D000521F81 /* CDROTestNamer.h */; }; AE48656F1B067953005DB302 /* AnyInstanceArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */; }; AE4865701B067953005DB302 /* AnyArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */; }; AE4865711B067953005DB302 /* AnyInstanceOfClassArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */; }; AE4865721B067953005DB302 /* AnyInstanceConformingToProtocolArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */; }; AE4865731B067953005DB302 /* CDRProtocolFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74906E15B48690008EA127 /* CDRProtocolFake.mm */; }; AE4865741B067953005DB302 /* CDRSpy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6628FC9B14C4DEC50016652A /* CDRSpy.mm */; }; AE4865751B067953005DB302 /* CDRClassFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */; }; AE4865761B067953005DB302 /* CedarDoubleImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */; }; AE4865771B067953005DB302 /* CDRFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74907015B486CD008EA127 /* CDRFake.mm */; }; AE4865781B067953005DB302 /* CedarDouble.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */; }; AE4865791B067953005DB302 /* RejectedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A946018807DA6008566F5 /* RejectedMethod.mm */; }; AE48657A1B067953005DB302 /* StubbedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB1A74115F304A9002E4167 /* StubbedMethod.mm */; }; AE48657B1B067953005DB302 /* InvocationMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7873715F440980058A27B /* InvocationMatcher.mm */; }; AE48657C1B067953005DB302 /* HaveReceived.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7874C15F444A50058A27B /* HaveReceived.mm */; }; AE48657D1B067953005DB302 /* CDRSpyInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */; }; AE48657E1B067953005DB302 /* NSInvocation+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */; }; AE48657F1B067953005DB302 /* NSMethodSignature+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */; }; AE4865801B067953005DB302 /* CDRSpec+XCTestSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */; }; AE4865811B067953005DB302 /* CDRXCTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */; }; AE4865821B067953005DB302 /* CDRXCTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */; }; AE4865831B067953005DB302 /* NSInvocation+CDRXExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */; }; AE4865841B067953005DB302 /* NSBundle+MainBundleHijack.m in Sources */ = {isa = PBXBuildFile; fileRef = 960118BB1434867E00825FFF /* NSBundle+MainBundleHijack.m */; }; AE4865851B067953005DB302 /* CedarApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */; }; AE4865861B067954005DB302 /* StringifiersBase.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE02021717452006009A7915 /* StringifiersBase.mm */; }; AE4865871B067954005DB302 /* RaiseException.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE167EF115B216DA005960B9 /* RaiseException.mm */; }; AE4865881B067954005DB302 /* RespondTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17998F17F89C9700C38060 /* RespondTo.mm */; }; AE4865891B067954005DB302 /* ConformTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5898AADDDCB0B204C88D1199 /* ConformTo.mm */; }; AE48658A1B067954005DB302 /* CDROTestNamer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F483E31187D39D000521F81 /* CDROTestNamer.m */; }; AE48658B1B067954005DB302 /* CDRSlowTestStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */; }; AE48658C1B067954005DB302 /* CDRColorizedReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */; }; AE48658D1B067954005DB302 /* CDRDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */; }; AE48658E1B067954005DB302 /* CDRJUnitXMLReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */; }; AE48658F1B067954005DB302 /* CDROTestReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */; }; AE4865901B067954005DB302 /* CDRReportDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */; }; AE4865911B067954005DB302 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; }; AE4865921B067954005DB302 /* CDRBufferedDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */; }; AE4865931B067954005DB302 /* CDRExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC511DC27B800029872 /* CDRExample.m */; }; AE4865941B067954005DB302 /* CDRExampleBase.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC611DC27B800029872 /* CDRExampleBase.m */; }; AE4865951B067954005DB302 /* CDRExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */; }; AE4865961B067954005DB302 /* CDRFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC811DC27B800029872 /* CDRFunctions.m */; }; AE4865971B067954005DB302 /* CDRTestBundleRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */; }; AE4865981B067954005DB302 /* CDRRuntimeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */; }; AE4865991B067954005DB302 /* CDRSharedExampleGroupPool.m in Sources */ = {isa = PBXBuildFile; fileRef = AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */; }; AE48659A1B067954005DB302 /* CDRSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC911DC27B800029872 /* CDRSpec.m */; }; AE48659B1B067954005DB302 /* CDRSpecFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEF360619DE21DB00794484 /* CDRSpecFailure.m */; }; AE48659C1B067954005DB302 /* CDRSpecHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */; }; AE48659D1B067954005DB302 /* CDRSymbolicator.m in Sources */ = {isa = PBXBuildFile; fileRef = 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */; }; AE48659E1B067954005DB302 /* CDRTypeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */; }; AE48659F1B067954005DB302 /* CDRNil.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */; }; AE4865A41B0690AF005DB302 /* NSInvocation+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */; }; AE4865A51B0690AF005DB302 /* Argument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136015D1425C003AAB9C /* Argument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865A61B0690AF005DB302 /* ValueArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136315D14274003AAB9C /* ValueArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865A71B0690AF005DB302 /* AnyInstanceArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865A81B0690AF005DB302 /* ReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136615D142E3003AAB9C /* ReturnValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865A91B0690AF005DB302 /* AnyArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136915D1439B003AAB9C /* AnyArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AA1B0690AF005DB302 /* AnyInstanceOfClassArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AB1B0690AF005DB302 /* AnyInstanceConformingToProtocolArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AC1B0690AF005DB302 /* CDRProtocolFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74902E15B45E80008EA127 /* CDRProtocolFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AD1B0690AF005DB302 /* CedarDoubles.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC8714C4DBA70016652A /* CedarDoubles.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AE1B0690AF005DB302 /* CDRSpy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC9814C4DD440016652A /* CDRSpy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865AF1B0690AF005DB302 /* CDRClassFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA67915AB72DA00617E1A /* CDRClassFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B01B0690AF005DB302 /* HaveReceived.h in Headers */ = {isa = PBXBuildFile; fileRef = 6639A78014C50D3000B564B7 /* HaveReceived.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B11B0690AF005DB302 /* CedarDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA68815AC728A00617E1A /* CedarDouble.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B21B0690AF005DB302 /* RejectedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A945D1880792E008566F5 /* RejectedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B31B0690AF005DB302 /* StubbedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6D115AE082500617E1A /* StubbedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B41B0690AF005DB302 /* InvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B51B0690B0005DB302 /* CDRFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74907315B488BE008EA127 /* CDRFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B61B0690B0005DB302 /* CedarApplicationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDA11DC27B800029872 /* CedarApplicationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B71B0690B0005DB302 /* Cedar-iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FCA014C503530016652A /* Cedar-iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B81B0690B0005DB302 /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFB13ECC21E00786282 /* Base.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865B91B0690B0005DB302 /* BeCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFC13ECC21E00786282 /* BeCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BA1B0690B0005DB302 /* BeFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A9457187F7D8F008566F5 /* BeFalsy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BB1B0690B0005DB302 /* BeGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BC1B0690B0005DB302 /* BeGTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF3300B145B4F75002F93BB /* BeGTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BD1B0690B0005DB302 /* BeInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BE1B0690B0005DB302 /* BeLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33016145B6222002F93BB /* BeLessThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865BF1B0690B0005DB302 /* BeLTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33020145B69DE002F93BB /* BeLTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C01B0690B0005DB302 /* BeNil.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFE13ECC21E00786282 /* BeNil.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C11B0690B0005DB302 /* BeSameInstanceAs.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C21B0690B0005DB302 /* BeTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300013ECC21E00786282 /* BeTruthy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C31B0690B0005DB302 /* ConformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C41B0690B0005DB302 /* Equal.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7300113ECC21E00786282 /* Equal.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C51B0690B0005DB302 /* Exist.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0721E2187518FD0031CC42 /* Exist.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C61B0690B0005DB302 /* RaiseException.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB45A901496C8D800845D09 /* RaiseException.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C71B0690B0005DB302 /* RespondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = CA17998C17F89C4B00C38060 /* RespondTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C81B0690B0005DB302 /* StringifiersBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303813ECCB7B00786282 /* StringifiersBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865C91B0690B0005DB302 /* StringifiersContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303913ECCB7B00786282 /* StringifiersContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CA1B0690B0005DB302 /* ComparatorsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D213F45BE500C8872C /* ComparatorsBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CB1B0690B0005DB302 /* ComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CC1B0690B0005DB302 /* CompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF3145A2E91002F93BB /* CompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CD1B0690B0005DB302 /* CompareGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CE1B0690B0005DB302 /* ComparatorsContainerConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865CF1B0690B0005DB302 /* CompareCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D01B0690B0005DB302 /* ActualValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF58413E9E87E00029396 /* ActualValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D11B0690B1005DB302 /* CedarMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D21B0690B1005DB302 /* CedarComparators.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7713EC730700786282 /* CedarComparators.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D31B0690B1005DB302 /* CedarStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7A13EC734000786282 /* CedarStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D51B0690B1005DB302 /* ShouldSyntax.h in Headers */ = {isa = PBXBuildFile; fileRef = AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D61B0690B1005DB302 /* CDRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D71B0690B1005DB302 /* CDRExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCC11DC27B800029872 /* CDRExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D81B0690B1005DB302 /* CDRExampleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865D91B0690B1005DB302 /* CDRExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DA1B0690B1005DB302 /* CDRExampleParent.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DB1B0690B1005DB302 /* CDRFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD111DC27B800029872 /* CDRFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DC1B0690B1005DB302 /* CDRHooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 2234907C18009DA6001C8E8D /* CDRHooks.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DD1B0690B1005DB302 /* CDRSharedExampleGroupPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DE1B0690B1005DB302 /* CDRSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD211DC27B800029872 /* CDRSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865DF1B0690B1005DB302 /* CDRSpecFailure.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865E01B0690B1005DB302 /* CDRSymbolicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */; }; AE4865E11B0690B1005DB302 /* Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD311DC27B800029872 /* Cedar.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865E21B0690B2005DB302 /* CDRSpecHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865E31B0690B2005DB302 /* CDRBlockHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */; }; AE4865E41B0690B2005DB302 /* CDRTypeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */; }; AE4865E51B0690B2005DB302 /* CDRNil.h in Headers */ = {isa = PBXBuildFile; fileRef = 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */; }; AE4865E61B0690B2005DB302 /* CDRSlowTestStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */; }; AE4865E71B0691C9005DB302 /* CDRColorizedReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865E81B0691EA005DB302 /* CDRTeamCityReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865E91B069253005DB302 /* CDRDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865EA1B069253005DB302 /* CDRExampleReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865EB1B069253005DB302 /* CDRJUnitXMLReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865EC1B069253005DB302 /* CDROTestReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865ED1B069353005DB302 /* BeEmpty.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7301013ECC25000786282 /* BeEmpty.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865EE1B069353005DB302 /* Contain.h in Headers */ = {isa = PBXBuildFile; fileRef = AE18A7FA13F4601400C8872C /* Contain.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865EF1B069353005DB302 /* AnInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865F01B069353005DB302 /* UIGeometryCompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865F11B069353005DB302 /* UIGeometryStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4865F21B069353005DB302 /* UIKitComparatorsContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 34D4B5C418F3B68900FB2C3B /* UIKitComparatorsContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4A9458187F7D8F008566F5 /* BeFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A9457187F7D8F008566F5 /* BeFalsy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4A9459187F7D8F008566F5 /* BeFalsy.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE4A9457187F7D8F008566F5 /* BeFalsy.h */; }; AE4A945B187F7E52008566F5 /* BeFalsySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */; }; AE4A945C187F7E52008566F5 /* BeFalsySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */; }; AE4A945E1880792E008566F5 /* RejectedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4A945D1880792E008566F5 /* RejectedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE4A945F1880792E008566F5 /* RejectedMethod.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE4A945D1880792E008566F5 /* RejectedMethod.h */; }; AE4A946118807DA6008566F5 /* RejectedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A946018807DA6008566F5 /* RejectedMethod.mm */; }; AE4A946218807DA6008566F5 /* RejectedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE4A946018807DA6008566F5 /* RejectedMethod.mm */; }; AE4E9B9219C8B44700D794CE /* NSInvocation+CDRXExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */; }; AE4E9B9419C8B44700D794CE /* NSInvocation+CDRXExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */; }; AE4E9B9519C8B44700D794CE /* NSInvocation+CDRXExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */; }; AE5218D3175979CA00A656BC /* ObjectWithWeakDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE5218D5175979D900A656BC /* WeakReferenceCompatibilitySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */; }; AE53B67E17E7BCAA00D83D5E /* CDRClassFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */; }; AE53B67F17E7BCAA00D83D5E /* CDRProtocolFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */; }; AE53B68017E7BCAA00D83D5E /* CDRSpySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */; }; AE53B68117E7BCD300D83D5E /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; AE53B68217E7BCE700D83D5E /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; AE53B68317E7BDA900D83D5E /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; AE53B68417E7CD8D00D83D5E /* ObjectWithWeakDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE55BF1B19A7CF58005948E6 /* CDRRuntimeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */; }; AE55BF1C19A7CF58005948E6 /* CDRRuntimeUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */; }; AE55BF1E19A7CFAB005948E6 /* CDRRuntimeUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */; }; AE597B4115B0638B00EEF305 /* InvocationMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = AE597B4015B0638B00EEF305 /* InvocationMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE6F3F341458D7C100C98F1E /* BeGreaterThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */; }; AE6F3F351458D7C100C98F1E /* BeGreaterThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */; }; AE71E7CC175E958F002A54D5 /* ARCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AE71E7CB175E958F002A54D5 /* ARCViewController.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AE74902F15B45E80008EA127 /* CDRProtocolFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74902E15B45E80008EA127 /* CDRProtocolFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE74903215B45EBA008EA127 /* CDRProtocolFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */; }; AE74903515B45EEE008EA127 /* CDRProtocolFake.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE74902E15B45E80008EA127 /* CDRProtocolFake.h */; }; AE74906F15B48690008EA127 /* CDRProtocolFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74906E15B48690008EA127 /* CDRProtocolFake.mm */; }; AE74907115B486CD008EA127 /* CDRFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74907015B486CD008EA127 /* CDRFake.mm */; }; AE74907215B486CD008EA127 /* CDRFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74907015B486CD008EA127 /* CDRFake.mm */; }; AE74907415B493B5008EA127 /* CDRFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE74907315B488BE008EA127 /* CDRFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE74907515B493B6008EA127 /* CDRFake.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE74907315B488BE008EA127 /* CDRFake.h */; }; AE74907715B493C4008EA127 /* CDRProtocolFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE74906E15B48690008EA127 /* CDRProtocolFake.mm */; }; AE7DD11217296CB20058EB3B /* CedarApplicationDelegateSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */; }; AE7F1708172730B000E1146D /* NSInvocation+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */; }; AE7F170B172730B000E1146D /* NSInvocation+Cedar.m in Sources */ = {isa = PBXBuildFile; fileRef = AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */; }; AE80788D183C71950078C608 /* ArgumentReleaser.m in Sources */ = {isa = PBXBuildFile; fileRef = AE807888183C71950078C608 /* ArgumentReleaser.m */; }; AE80788F183C71950078C608 /* ArgumentReleaser.m in Sources */ = {isa = PBXBuildFile; fileRef = AE807888183C71950078C608 /* ArgumentReleaser.m */; }; AE807890183C71950078C608 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; AE807892183C71950078C608 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; AE807893183C71950078C608 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; AE807895183C71950078C608 /* SimpleKeyValueObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */; }; AE84F0DB145B70DD00769F85 /* ShouldSyntax.h in Headers */ = {isa = PBXBuildFile; fileRef = AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE8C87AE136245BB006C9305 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; AE8C87AF136245BD006C9305 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; AE8C880F13626FA5006C9305 /* CDRSpecFailure.h in Headers */ = {isa = PBXBuildFile; fileRef = AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE91CA6C11DE64A3002BA6B9 /* CDRSharedExampleGroupPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE91CA6D11DE64B3002BA6B9 /* CDRSharedExampleGroupPool.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */; }; AE94D03F15F341B200A0C2B7 /* AnyInstanceArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE94D04015F341B200A0C2B7 /* AnyInstanceArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */; }; AE94D04515F3449500A0C2B7 /* AnyInstanceArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */; }; AE94D04615F3449500A0C2B7 /* AnyInstanceArgument.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */; }; AE9855AE1236E7080024094E /* CDRSharedExampleGroupPool.m in Sources */ = {isa = PBXBuildFile; fileRef = AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */; }; AE9AA67515AB601500617E1A /* CedarDoubles.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC8714C4DBA70016652A /* CedarDoubles.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA67615AB601500617E1A /* CDRSpy.h in Headers */ = {isa = PBXBuildFile; fileRef = 6628FC9814C4DD440016652A /* CDRSpy.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA67815AB601500617E1A /* HaveReceived.h in Headers */ = {isa = PBXBuildFile; fileRef = 6639A78014C50D3000B564B7 /* HaveReceived.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA67B15AB72DA00617E1A /* CDRClassFake.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA67915AB72DA00617E1A /* CDRClassFake.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA68015AB748E00617E1A /* CDRClassFakeSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */; }; AE9AA68215AB76DB00617E1A /* CDRClassFake.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE9AA67915AB72DA00617E1A /* CDRClassFake.h */; }; AE9AA68615AB7A8700617E1A /* CDRClassFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */; }; AE9AA68715AB7E0900617E1A /* CDRClassFake.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */; }; AE9AA68915AC729800617E1A /* CedarDouble.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA68815AC728A00617E1A /* CedarDouble.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA68A15AC729E00617E1A /* CedarDouble.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE9AA68815AC728A00617E1A /* CedarDouble.h */; }; AE9AA69715ADB99800617E1A /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; AE9AA69815ADB99800617E1A /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; AE9AA6D315AE087C00617E1A /* StubbedMethod.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE9AA6D115AE082500617E1A /* StubbedMethod.h */; }; AE9AA6D415AE087D00617E1A /* StubbedMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6D115AE082500617E1A /* StubbedMethod.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE9AA6DB15AE0B0400617E1A /* CedarDoubleImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */; }; AE9AA6DE15AE0BE200617E1A /* CedarDoubleImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */; }; AE9AA6DF15AE0BE200617E1A /* CedarDoubleImpl.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */; }; AE9BA627184D203000079A97 /* ConformTo.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */; }; AE9EAAD9178C789800CCF7DA /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; AE9EAADA178C789900CCF7DA /* CDRDefaultReporterSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */; }; AEA8962C19D0C242007D5C08 /* CDRTestBundleRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */; }; AEAA191219DCC5A900194E95 /* NSInvocation+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */; }; AEAA191419DCC5A900194E95 /* NSMethodSignature+Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */; }; AEB1A74215F304A9002E4167 /* StubbedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB1A74115F304A9002E4167 /* StubbedMethod.mm */; }; AEB1A74315F304A9002E4167 /* StubbedMethod.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEB1A74115F304A9002E4167 /* StubbedMethod.mm */; }; AEB45A911496C8D800845D09 /* RaiseException.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB45A901496C8D800845D09 /* RaiseException.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEB45A921496C8D800845D09 /* RaiseException.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEB45A901496C8D800845D09 /* RaiseException.h */; }; AEB9B2CB1B23F5DF003E4728 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360D19DF24AB00794484 /* image.png */; }; AEB9B2CC1B23F5FB003E4728 /* edward.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360F19DF27E400794484 /* edward.jpg */; }; AEBB92611496C1F000EEBD59 /* RaiseExceptionSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */; }; AEBB92631496C1F000EEBD59 /* RaiseExceptionSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */; }; AEC40C50174AC4C700474D2D /* UIGeometryCompareEqual.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */; }; AEC40C51174AC4C700474D2D /* UIGeometryStringifiers.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */; }; AEC40C54174AC51D00474D2D /* UIKitEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */; }; AEC40C58174ACAD900474D2D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEC40C57174ACAD900474D2D /* UIKit.framework */; }; AEC7873915F440980058A27B /* InvocationMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7873715F440980058A27B /* InvocationMatcher.mm */; }; AEC7873A15F440980058A27B /* InvocationMatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7873715F440980058A27B /* InvocationMatcher.mm */; }; AEC7874D15F444A50058A27B /* HaveReceived.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7874C15F444A50058A27B /* HaveReceived.mm */; }; AEC7874E15F444A50058A27B /* HaveReceived.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEC7874C15F444A50058A27B /* HaveReceived.mm */; }; AEC9DEED12C2CC7E0039512D /* CDRColorizedReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEC9DEEE12C2CC7E0039512D /* CDRColorizedReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */; }; AEC9DEF112C2CC7E0039512D /* CDRColorizedReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */; }; AEC9DEF412C2CC8F0039512D /* CDRColorizedReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */; }; AECF136115D1425C003AAB9C /* Argument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136015D1425C003AAB9C /* Argument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AECF136215D1425C003AAB9C /* Argument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AECF136015D1425C003AAB9C /* Argument.h */; }; AECF136415D14274003AAB9C /* ValueArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136315D14274003AAB9C /* ValueArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AECF136515D14274003AAB9C /* ValueArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AECF136315D14274003AAB9C /* ValueArgument.h */; }; AECF136715D142E3003AAB9C /* ReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136615D142E3003AAB9C /* ReturnValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; AECF136815D142E3003AAB9C /* ReturnValue.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AECF136615D142E3003AAB9C /* ReturnValue.h */; }; AECF136A15D1439B003AAB9C /* AnyArgument.h in Headers */ = {isa = PBXBuildFile; fileRef = AECF136915D1439B003AAB9C /* AnyArgument.h */; settings = {ATTRIBUTES = (Public, ); }; }; AECF136B15D1439B003AAB9C /* AnyArgument.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AECF136915D1439B003AAB9C /* AnyArgument.h */; }; AED10EBC18F46C0E00950904 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; AED10EBD18F46C0E00950904 /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; AEE0665617315C20003CA143 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; AEE0665717315C20003CA143 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; AEE0665917315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; AEE0665A17315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; AEE8DBD4175FFCF3008AF18A /* CDRSpyInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */; }; AEE8DBD7175FFCF3008AF18A /* CDRSpyInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */; }; AEE8DBD8175FFCF3008AF18A /* CDRSpyInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */; }; AEEE1FF311DC27B800029872 /* CDRDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */; }; AEEE1FF411DC27B800029872 /* CDRExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC511DC27B800029872 /* CDRExample.m */; }; AEEE1FF511DC27B800029872 /* CDRExampleBase.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC611DC27B800029872 /* CDRExampleBase.m */; }; AEEE1FF611DC27B800029872 /* CDRExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */; }; AEEE1FF711DC27B800029872 /* CDRFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC811DC27B800029872 /* CDRFunctions.m */; }; AEEE1FF811DC27B800029872 /* CDRSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC911DC27B800029872 /* CDRSpec.m */; }; AEEE1FF911DC27B800029872 /* CDRDefaultReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFA11DC27B800029872 /* CDRExample.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCC11DC27B800029872 /* CDRExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFB11DC27B800029872 /* CDRExampleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFC11DC27B800029872 /* CDRExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFD11DC27B800029872 /* CDRExampleParent.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFE11DC27B800029872 /* CDRExampleReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE1FFF11DC27B800029872 /* CDRFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD111DC27B800029872 /* CDRFunctions.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE200011DC27B800029872 /* CDRSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD211DC27B800029872 /* CDRSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE200111DC27B800029872 /* Cedar.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FD311DC27B800029872 /* Cedar.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE200811DC27B800029872 /* CDRSpecHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEEE201111DC27B800029872 /* CDRSpecHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */; }; AEEE21BE11DC290400029872 /* CDRExampleGroupSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */; }; AEEE21BF11DC290400029872 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AEEE21C111DC290400029872 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FEF11DC27B800029872 /* main.mm */; }; AEEE21C211DC290400029872 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AEEE21C311DC290400029872 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AEEE21C411DC290400029872 /* SpecSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF211DC27B800029872 /* SpecSpec2.m */; }; AEEE220311DC29AC00029872 /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE1FB611DC271300029872 /* Cedar.framework */; }; AEEE223111DC2B6500029872 /* CDRDefaultReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */; }; AEEE223211DC2B6500029872 /* CDRExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC511DC27B800029872 /* CDRExample.m */; }; AEEE223311DC2B6500029872 /* CDRExampleBase.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC611DC27B800029872 /* CDRExampleBase.m */; }; AEEE223411DC2B6500029872 /* CDRExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */; }; AEEE223511DC2B6500029872 /* CDRFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC811DC27B800029872 /* CDRFunctions.m */; }; AEEE223611DC2B6500029872 /* CDRSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FC911DC27B800029872 /* CDRSpec.m */; }; AEEE223711DC2B6500029872 /* CDRSpecHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */; }; AEEE223D11DC2B6D00029872 /* CedarApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */; }; AEEE226011DC2C8300029872 /* CDRFunctions.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FD111DC27B800029872 /* CDRFunctions.h */; }; AEEE226111DC2C8300029872 /* Cedar.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FD311DC27B800029872 /* Cedar.h */; }; AEEE226211DC2C8300029872 /* CDRSpecHelper.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */; }; AEEE227E11DC2D3A00029872 /* libCedar.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE222911DC2B0600029872 /* libCedar.a */; }; AEEE228011DC2D5200029872 /* CDRExampleSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */; }; AEEE228311DC2D5200029872 /* CDRHooksSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */; }; AEEE228411DC2D5200029872 /* SpecSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF111DC27B800029872 /* SpecSpec.mm */; }; AEEE228511DC2D5200029872 /* SpecSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FF211DC27B800029872 /* SpecSpec2.m */; }; AEEE228711DC2D5800029872 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEE1FED11DC27B800029872 /* main.mm */; }; AEEF360719DE21DB00794484 /* CDRSpecFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEF360619DE21DB00794484 /* CDRSpecFailure.m */; }; AEEF360819DE21ED00794484 /* CDRSpecFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEF360619DE21DB00794484 /* CDRSpecFailure.m */; }; AEEF360E19DF24AB00794484 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360D19DF24AB00794484 /* image.png */; }; AEEF361019DF27E400794484 /* edward.jpg in Resources */ = {isa = PBXBuildFile; fileRef = AEEF360F19DF27E400794484 /* edward.jpg */; }; AEF32FF2145A2D79002F93BB /* BeGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF32FF4145A2E91002F93BB /* CompareEqual.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF3145A2E91002F93BB /* CompareEqual.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF32FF5145A2EAC002F93BB /* BeGreaterThan.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */; }; AEF32FF6145A2ECA002F93BB /* CompareEqual.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF32FF3145A2E91002F93BB /* CompareEqual.h */; }; AEF32FF8145A2EDF002F93BB /* CompareGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF32FF9145A2EDF002F93BB /* CompareGreaterThan.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */; }; AEF33009145B4E3B002F93BB /* BeGTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33008145B4E3B002F93BB /* BeGTESpec.mm */; }; AEF3300A145B4E3B002F93BB /* BeGTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33008145B4E3B002F93BB /* BeGTESpec.mm */; }; AEF3300C145B4F75002F93BB /* BeGTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF3300B145B4F75002F93BB /* BeGTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF3300D145B4F75002F93BB /* BeGTE.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF3300B145B4F75002F93BB /* BeGTE.h */; }; AEF33015145B6188002F93BB /* BeLessThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33012145B6188002F93BB /* BeLessThanSpec.mm */; }; AEF33017145B6222002F93BB /* BeLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33016145B6222002F93BB /* BeLessThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF33018145B6222002F93BB /* BeLessThan.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF33016145B6222002F93BB /* BeLessThan.h */; }; AEF3301C145B62E9002F93BB /* BeLessThanSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF33012145B6188002F93BB /* BeLessThanSpec.mm */; }; AEF3301E145B68D7002F93BB /* BeLTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF3301D145B68D7002F93BB /* BeLTESpec.mm */; }; AEF3301F145B68D7002F93BB /* BeLTESpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF3301D145B68D7002F93BB /* BeLTESpec.mm */; }; AEF33021145B69DE002F93BB /* BeLTE.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF33020145B69DE002F93BB /* BeLTE.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF33022145B69DE002F93BB /* BeLTE.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF33020145B69DE002F93BB /* BeLTE.h */; }; AEF72F7813EC730700786282 /* CedarComparators.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7713EC730700786282 /* CedarComparators.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF72F7913EC732000786282 /* CedarComparators.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72F7713EC730700786282 /* CedarComparators.h */; }; AEF72F7B13EC734000786282 /* CedarStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF72F7A13EC734000786282 /* CedarStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF72F7C13EC735400786282 /* CedarStringifiers.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF72F7A13EC734000786282 /* CedarStringifiers.h */; }; AEF7301113ECC25000786282 /* BeEmpty.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7301013ECC25000786282 /* BeEmpty.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF7301B13ECC4AE00786282 /* BeCloseToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */; }; AEF7301C13ECC4AE00786282 /* BeCloseToSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */; }; AEF7301D13ECC4AE00786282 /* BeInstanceOfSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */; }; AEF7301E13ECC4AE00786282 /* BeInstanceOfSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */; }; AEF7301F13ECC4AE00786282 /* BeNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301613ECC4AE00786282 /* BeNilSpec.mm */; }; AEF7302013ECC4AE00786282 /* BeNilSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301613ECC4AE00786282 /* BeNilSpec.mm */; }; AEF7302113ECC4AE00786282 /* BeSameInstanceAsSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */; }; AEF7302213ECC4AE00786282 /* BeSameInstanceAsSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */; }; AEF7302313ECC4AE00786282 /* BeTruthySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */; }; AEF7302413ECC4AE00786282 /* BeTruthySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */; }; AEF7302513ECC4AE00786282 /* EqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301913ECC4AE00786282 /* EqualSpec.mm */; }; AEF7302613ECC4AE00786282 /* EqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301913ECC4AE00786282 /* EqualSpec.mm */; }; AEF7302713ECC4AE00786282 /* MutableEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */; }; AEF7302813ECC4AE00786282 /* MutableEqualSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */; }; AEF7302C13ECC4E700786282 /* BeEmptySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */; }; AEF7302D13ECC4E700786282 /* BeEmptySpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */; }; AEF7303A13ECCB7B00786282 /* StringifiersBase.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303813ECCB7B00786282 /* StringifiersBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF7303B13ECCB7B00786282 /* StringifiersContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF7303913ECCB7B00786282 /* StringifiersContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF8FB0719E6000E00DD4FE4 /* CDRVersion.h in Headers */ = {isa = PBXBuildFile; fileRef = AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */; settings = {ATTRIBUTES = (Public, ); }; }; AEF8FB0819E6000E00DD4FE4 /* CDRVersion.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */; }; AEFD163411DCFDC800F4448A /* CedarApplicationDelegate.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FDA11DC27B800029872 /* CedarApplicationDelegate.h */; }; AEFD166111DCFEC900F4448A /* CDRExampleReporter.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */; }; AEFD167A11DCFF1700F4448A /* CDRSpec.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FD211DC27B800029872 /* CDRSpec.h */; }; AEFD168211DCFF3B00F4448A /* CDRExampleBase.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */; }; AEFD168D11DCFF8600F4448A /* CDRExampleParent.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */; }; AEFD17BB11DD1E9E00F4448A /* CDRSharedExampleGroupPool.m in Sources */ = {isa = PBXBuildFile; fileRef = AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */; }; B86B685F1A1326E200F283F7 /* OSXGeometryStringifiers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0F354819E705C700B9F116 /* OSXGeometryStringifiers.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA17998D17F89C4B00C38060 /* RespondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = CA17998C17F89C4B00C38060 /* RespondTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA17998E17F89C4B00C38060 /* RespondTo.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = CA17998C17F89C4B00C38060 /* RespondTo.h */; }; CA17999017F89C9700C38060 /* RespondTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17998F17F89C9700C38060 /* RespondTo.mm */; }; CA17999117F89C9700C38060 /* RespondTo.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17998F17F89C9700C38060 /* RespondTo.mm */; }; E31179D2161FD937007D3CDE /* CDRSlowTestStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */; }; E31179D5161FD937007D3CDE /* CDRSlowTestStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */; }; E31179D6161FD937007D3CDE /* CDRSlowTestStatistics.m in Sources */ = {isa = PBXBuildFile; fileRef = E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */; }; E32861321604F287001FA77E /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; E32861331604F287001FA77E /* FibonacciCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E32861311604F287001FA77E /* FibonacciCalculator.m */; }; E4BCFDD21817FA110083ED98 /* ObjectWithProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */; }; E4BCFDD31817FA110083ED98 /* ObjectWithProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */; }; F71C2F341D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F361D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F371D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F381D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F391D3DADD0003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F3A1D3DADD1003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F71C2F3B1D3DADD1003B37DC /* CedarTestSpecBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */; }; F78FDA161B43AA8C0054C768 /* CedarNiceFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */; }; F78FDA181B43AA8F0054C768 /* CedarOrdinaryFakeSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */; }; F78FDA1A1B43AA930054C768 /* HaveReceivedSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */; }; F78FDA1B1B43AB540054C768 /* SimpleIncrementer.m in Sources */ = {isa = PBXBuildFile; fileRef = AE80788A183C71950078C608 /* SimpleIncrementer.m */; }; F78FDA1D1B43ABBC0054C768 /* ExpectFailureWithMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */; }; F7A225DC1B43A8FB006231CC /* FooSuperclass.m in Sources */ = {isa = PBXBuildFile; fileRef = AED10EBB18F46C0E00950904 /* FooSuperclass.m */; }; F7BBE7D31B43A852009547F0 /* CedarDoubleSharedExamples.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */; }; F7C8F3041BC63A000088069D /* ContainSubsetSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */; }; F7C8F3061BC63A000088069D /* ContainSubsetSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */; }; F7C8F3071BC63A000088069D /* ContainSubsetSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */; }; F7C8F30B1BC63A000088069D /* ContainSubsetSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */; }; F7C8F30C1BC63A000088069D /* ContainSubsetSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */; }; F7C9BBED1D3E83E500B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBEE1D3E83EB00B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBEF1D3E83EB00B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBF01D3E83F100B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBF11D3E83F200B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBF21D3E83F200B694C0 /* CDRSpecRunSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */; }; F7C9BBF61D3E85FF00B694C0 /* CDRStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */; }; F7C9BBF71D3E860000B694C0 /* CDRStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */; }; F7C9BBF81D3E860100B694C0 /* CDRStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */; }; F7C9BBF91D3E860100B694C0 /* CDRStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */; }; F7C9BBFA1D3E860200B694C0 /* CDRStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */; }; F7C9BC011D45E16200B694C0 /* CDRRunState.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */; }; F7C9BC021D45E16200B694C0 /* CDRRunState.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BC001D45E16200B694C0 /* CDRRunState.m */; }; F7C9BC031D45E19A00B694C0 /* CDRRunState.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BC001D45E16200B694C0 /* CDRRunState.m */; }; F7C9BC041D45E19B00B694C0 /* CDRRunState.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BC001D45E16200B694C0 /* CDRRunState.m */; }; F7C9BC051D45E19B00B694C0 /* CDRRunState.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BC001D45E16200B694C0 /* CDRRunState.m */; }; F7C9BC061D45E19C00B694C0 /* CDRRunState.m in Sources */ = {isa = PBXBuildFile; fileRef = F7C9BC001D45E16200B694C0 /* CDRRunState.m */; }; F7C9BC071D45E4E000B694C0 /* CDRRunState.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */; }; F7C9BC081D45E4E100B694C0 /* CDRRunState.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */; }; F7C9BC091D45E4E100B694C0 /* CDRRunState.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */; }; F7C9BC0A1D45E4E400B694C0 /* CDRStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */; }; F7C9BC0B1D45E4E500B694C0 /* CDRStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */; }; F7C9BC0C1D45E4E500B694C0 /* CDRStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */; }; F7C9BC0D1D45E4E600B694C0 /* CDRStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */; }; F7C9BC0E1D45E4EC00B694C0 /* CDRStateTracking.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */; }; F7C9BC0F1D45E4EC00B694C0 /* CDRStateTracking.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */; }; F7C9BC101D45E4ED00B694C0 /* CDRStateTracking.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */; }; F7C9BC111D45E4ED00B694C0 /* CDRStateTracking.h in Headers */ = {isa = PBXBuildFile; fileRef = F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */; }; F7F4099B1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */; }; F7F4099C1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */; }; F7F4099D1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 1F45A3CC180E4796003C1E36 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = 96B5F9F5144A81A7000A6A5D; remoteInfo = OCUnitApp; }; 346262861B99C1DC002CAEBD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = 346262831B99C1DC002CAEBD; remoteInfo = "Cedar-watchOS Specs Extension"; }; 3462629D1B99D0BB002CAEBD /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = 346261DE1B995239002CAEBD; remoteInfo = "Cedar-watchOS"; }; 346D1AA61BBC406000BECD4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE222811DC2B0600029872; remoteInfo = "Cedar-iOS StaticLib"; }; 34852D231BBE36B90072D249 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = 346262771B99C1DB002CAEBD; remoteInfo = "Cedar-watchOS Specs"; }; 34D7C4711BB9B72300E8E523 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = 34D7C3C91BB9747400E8E523; remoteInfo = "Cedar-tvOS"; }; 96A07EF013F276640021974D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE1FB511DC271300029872; remoteInfo = Cedar; }; AE02E80E184EADE100414F19 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE224B11DC2BBB00029872; remoteInfo = "Cedar-iOS"; }; AE03FC101B06C39500013784 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AE4864F71B067620005DB302; remoteInfo = "Cedar-iOS-Framework"; }; AE248FAB19DCD52500092C14 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AE248F9719DCD52500092C14; remoteInfo = "OS X Host App"; }; AE248FBF19DCD5E200092C14 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE1FB511DC271300029872; remoteInfo = Cedar; }; AE4865A21B067F53005DB302 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE222811DC2B0600029872; remoteInfo = "Cedar-StaticLib"; }; AEEE218A11DC28E700029872 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AEEE1FA611DC26EA00029872 /* Project object */; proxyType = 1; remoteGlobalIDString = AEEE1FB511DC271300029872; remoteInfo = Cedar; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ 346262981B99C1DC002CAEBD /* Embed App Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( 346262851B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex in Embed App Extensions */, ); name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; 3462629F1B99D0CA002CAEBD /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 346262A01B99D0DD002CAEBD /* Cedar.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; 34852D1C1BBE35FF0072D249 /* Embed Watch Content */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; dstSubfolderSpec = 16; files = ( 34852D1D1BBE35FF0072D249 /* Cedar-watchOS Specs.app in Embed Watch Content */, ); name = "Embed Watch Content"; runOnlyForDeploymentPostprocessing = 0; }; AE03FC121B06C39D00013784 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( AE03FC131B06C3BA00013784 /* Cedar.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; AEEE225E11DC2C5E00029872 /* Copy headers to framework */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = "${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal/${PRODUCT_NAME}.framework/Headers"; dstSubfolderSpec = 0; files = ( 34ADD2ED19220F9300B057AC /* AnyInstanceOfClassArgument.h in Copy headers to framework */, 34ADD2EE19220F9300B057AC /* AnyInstanceConformingToProtocolArgument.h in Copy headers to framework */, 34C95F541C2DD7B30055F089 /* CDRNullabilityCompat.h in Copy headers to framework */, 341477711914090000CBA385 /* AnInstanceOf.h in Copy headers to framework */, AE0F354F19E87D6F00B9F116 /* CompareCloseTo.h in Copy headers to framework */, 3414776F191406FC00CBA385 /* ComparatorsContainerConvenience.h in Copy headers to framework */, 34EBFD0F18FF505F005392AB /* UIKitComparatorsContainer.h in Copy headers to framework */, 34157D0C1B755DE0007AD1BA /* CDRDefaultReporter.h in Copy headers to framework */, 1FF3591117B6094A00096517 /* CDRExample.h in Copy headers to framework */, 1FF3591217B6094A00096517 /* CDRExampleGroup.h in Copy headers to framework */, AE18A7BF13F450BD00C8872C /* BeEmpty.h in Copy headers to framework */, AE18A7C013F450BD00C8872C /* StringifiersBase.h in Copy headers to framework */, AE18A7C113F450BD00C8872C /* StringifiersContainer.h in Copy headers to framework */, AEF72F7C13EC735400786282 /* CedarStringifiers.h in Copy headers to framework */, AEF72F7913EC732000786282 /* CedarComparators.h in Copy headers to framework */, AE0AF58613E9E89D00029396 /* ActualValue.h in Copy headers to framework */, AE0AF56C13E9C0FB00029396 /* CedarMatchers.h in Copy headers to framework */, AEFD163411DCFDC800F4448A /* CedarApplicationDelegate.h in Copy headers to framework */, AEEE226011DC2C8300029872 /* CDRFunctions.h in Copy headers to framework */, AEFD166111DCFEC900F4448A /* CDRExampleReporter.h in Copy headers to framework */, AEFD167A11DCFF1700F4448A /* CDRSpec.h in Copy headers to framework */, AEFD168211DCFF3B00F4448A /* CDRExampleBase.h in Copy headers to framework */, AEFD168D11DCFF8600F4448A /* CDRExampleParent.h in Copy headers to framework */, AE02E813184ECAEE00414F19 /* CDRSpecFailure.h in Copy headers to framework */, AE4A945F1880792E008566F5 /* RejectedMethod.h in Copy headers to framework */, AE0721E4187518FD0031CC42 /* Exist.h in Copy headers to framework */, AE91CA6D11DE64B3002BA6B9 /* CDRSharedExampleGroupPool.h in Copy headers to framework */, AEEE226111DC2C8300029872 /* Cedar.h in Copy headers to framework */, AEEE226211DC2C8300029872 /* CDRSpecHelper.h in Copy headers to framework */, AEC9DEF112C2CC7E0039512D /* CDRColorizedReporter.h in Copy headers to framework */, AE18A7B813F450A700C8872C /* Base.h in Copy headers to framework */, AE18A7B913F450A700C8872C /* BeCloseTo.h in Copy headers to framework */, 2234907F18009DAD001C8E8D /* CDRHooks.h in Copy headers to framework */, AE02E814184ECB0F00414F19 /* ShouldSyntax.h in Copy headers to framework */, AE18A7BA13F450A700C8872C /* BeInstanceOf.h in Copy headers to framework */, AE18A7BB13F450A700C8872C /* BeNil.h in Copy headers to framework */, AE18A7BC13F450A700C8872C /* BeSameInstanceAs.h in Copy headers to framework */, AE18A7BD13F450A700C8872C /* BeTruthy.h in Copy headers to framework */, AE18A7BE13F450A700C8872C /* Equal.h in Copy headers to framework */, AE18A7D413F45BE500C8872C /* ComparatorsBase.h in Copy headers to framework */, AE18A7D713F45BFC00C8872C /* ComparatorsContainer.h in Copy headers to framework */, AE18A7FC13F4601400C8872C /* Contain.h in Copy headers to framework */, AEF32FF5145A2EAC002F93BB /* BeGreaterThan.h in Copy headers to framework */, AEF32FF6145A2ECA002F93BB /* CompareEqual.h in Copy headers to framework */, AEF32FF9145A2EDF002F93BB /* CompareGreaterThan.h in Copy headers to framework */, AEF3300D145B4F75002F93BB /* BeGTE.h in Copy headers to framework */, 34157D111B755E40007AD1BA /* CDRBufferedDefaultReporter.h in Copy headers to framework */, AEF33018145B6222002F93BB /* BeLessThan.h in Copy headers to framework */, AEF33022145B69DE002F93BB /* BeLTE.h in Copy headers to framework */, AEB45A921496C8D800845D09 /* RaiseException.h in Copy headers to framework */, AE4A9459187F7D8F008566F5 /* BeFalsy.h in Copy headers to framework */, 34DB67541C2B8C1000206663 /* CedarReporters.h in Copy headers to framework */, 6628FC8914C4DBA70016652A /* CedarDoubles.h in Copy headers to framework */, 6628FC9A14C4DD440016652A /* CDRSpy.h in Copy headers to framework */, 6628FCA114C503530016652A /* Cedar-iOS.h in Copy headers to framework */, 6639A78214C50D3000B564B7 /* HaveReceived.h in Copy headers to framework */, AE9AA68215AB76DB00617E1A /* CDRClassFake.h in Copy headers to framework */, AE9AA68A15AC729E00617E1A /* CedarDouble.h in Copy headers to framework */, AE9AA6D315AE087C00617E1A /* StubbedMethod.h in Copy headers to framework */, 34DB674E1C2B65EC00206663 /* ContainSubset.h in Copy headers to framework */, AE74903515B45EEE008EA127 /* CDRProtocolFake.h in Copy headers to framework */, 22B6A22715B7ACF800960ADE /* InvocationMatcher.h in Copy headers to framework */, 34157D0E1B755E09007AD1BA /* CDROTestReporter.h in Copy headers to framework */, AE74907515B493B6008EA127 /* CDRFake.h in Copy headers to framework */, AECF136215D1425C003AAB9C /* Argument.h in Copy headers to framework */, AECF136515D14274003AAB9C /* ValueArgument.h in Copy headers to framework */, 346F64741B82D90900F64156 /* BlockMatcher.h in Copy headers to framework */, AECF136815D142E3003AAB9C /* ReturnValue.h in Copy headers to framework */, AE9BA627184D203000079A97 /* ConformTo.h in Copy headers to framework */, AECF136B15D1439B003AAB9C /* AnyArgument.h in Copy headers to framework */, AE94D04015F341B200A0C2B7 /* AnyInstanceArgument.h in Copy headers to framework */, 34157D0D1B755DFB007AD1BA /* CDRJUnitXMLReporter.h in Copy headers to framework */, AEF8FB0819E6000E00DD4FE4 /* CDRVersion.h in Copy headers to framework */, AEC40C50174AC4C700474D2D /* UIGeometryCompareEqual.h in Copy headers to framework */, 34157D101B755E21007AD1BA /* CDRTeamCityReporter.h in Copy headers to framework */, AEC40C51174AC4C700474D2D /* UIGeometryStringifiers.h in Copy headers to framework */, CA17998E17F89C4B00C38060 /* RespondTo.h in Copy headers to framework */, ); name = "Copy headers to framework"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1F45A3DD180E4796003C1E36 /* Cedar-iOS SpecBundle.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cedar-iOS SpecBundle.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 1F45A3E2180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SpecBundleApplicationTestsWithXCTest.m; path = SpecBundle/SpecBundleApplicationTestsWithXCTest.m; sourceTree = ""; }; 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDROTestReporterSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 1F483E30187D39D000521F81 /* CDROTestNamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDROTestNamer.h; sourceTree = ""; }; 1F483E31187D39D000521F81 /* CDROTestNamer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDROTestNamer.m; sourceTree = ""; }; 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeNil_ARCSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeSameInstanceAs_ARCSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 1FE15C191869091900207F0C /* CDRReportDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRReportDispatcher.h; sourceTree = ""; }; 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRReportDispatcher.m; sourceTree = ""; }; 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnyArgument.mm; sourceTree = ""; }; 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRBufferedDefaultReporter.m; sourceTree = ""; }; 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = CDRBufferedDefaultReporter.h; sourceTree = ""; }; 2234907C18009DA6001C8E8D /* CDRHooks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRHooks.h; sourceTree = ""; }; 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpyiOSSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 342FB2C61BC328320090E253 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRXCTestObserver.h; sourceTree = ""; }; 343FAFE8190FDAEC0085AFEC /* DeallocNotifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeallocNotifier.h; sourceTree = ""; }; 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeallocNotifier.m; sourceTree = ""; }; 345B1E881C31CC96009BB77D /* Spec-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Spec-Bridging-Header.h"; sourceTree = ""; }; 345B1E8D1C31DA2B009BB77D /* XCTAssertSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTAssertSpec.swift; sourceTree = ""; }; 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CDRBlockHelper.h; sourceTree = ""; }; 346261DF1B995239002CAEBD /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 346262781B99C1DB002CAEBD /* Cedar-watchOS Specs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-watchOS Specs.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 3462627F1B99C1DB002CAEBD /* App-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "App-Info.plist"; sourceTree = ""; }; 346262841B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Cedar-watchOS Specs Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 3462628D1B99C1DC002CAEBD /* ExtensionDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ExtensionDelegate.mm; sourceTree = ""; }; 346262911B99C1DC002CAEBD /* Extension-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Extension-Info.plist"; sourceTree = ""; }; 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRTypeUtilities.m; sourceTree = ""; }; 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CDRTypeUtilities.h; sourceTree = ""; }; 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRTypeUtilitiesSpec.mm; sourceTree = ""; }; 346D1A981BBB389A00BECD4B /* SpecBundle-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "SpecBundle-Info.plist"; path = "SpecBundle/SpecBundle-Info.plist"; sourceTree = ""; }; 346D1AA21BBB457900BECD4B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 346D1AA91BBC41FE00BECD4B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 346D1AAC1BBC46B600BECD4B /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 346F64681B82D01700F64156 /* BlockMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockMatcher.h; sourceTree = ""; }; 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockMatcherSpec.mm; sourceTree = ""; }; 34757E201BA466050047BC8D /* TestObservationHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObservationHelper.h; sourceTree = ""; }; 34757E211BA466050047BC8D /* TestObservationHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestObservationHelper.m; sourceTree = ""; }; 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRPrivateFunctions.h; sourceTree = ""; }; 34852D211BBE35FF0072D249 /* Cedar-watchOS HostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-watchOS HostApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 34852D251BBE38EE0072D249 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRXCTestFunctions.m; sourceTree = ""; }; 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CDRXCTestSupport.h; sourceTree = ""; }; 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSpecRun.h; sourceTree = ""; }; 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpecRun.m; sourceTree = ""; }; 34A848551B9A491E00396A09 /* Interface.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Interface.storyboard; sourceTree = ""; }; 34A848571B9A4A0500396A09 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS2.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnyInstanceOfClassArgument.h; sourceTree = ""; }; 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnyInstanceOfClassArgument.mm; sourceTree = ""; }; 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AnyInstanceConformingToProtocolArgument.h; sourceTree = ""; }; 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnyInstanceConformingToProtocolArgument.mm; sourceTree = ""; }; 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMethodSignature+Cedar.m"; sourceTree = ""; }; 34AF814C1C53339300DB5249 /* TestReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestReporter.h; sourceTree = ""; }; 34AF814D1C53339300DB5249 /* TestReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestReporter.m; sourceTree = ""; }; 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRNullabilityCompat.h; sourceTree = ""; }; 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AnInstanceOf.h; path = ../Comparators/AnInstanceOf.h; sourceTree = ""; }; 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIKitContainSpec.mm; sourceTree = ""; }; 34D4B5C418F3B68900FB2C3B /* UIKitComparatorsContainer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIKitComparatorsContainer.h; sourceTree = ""; }; 34D7C3CA1BB9747400E8E523 /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34D7C4691BB9B71600E8E523 /* Cedar-tvOS SpecBundle.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cedar-tvOS SpecBundle.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 34D7C4B71BB9CB5700E8E523 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; }; 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSpec.swift; sourceTree = ""; }; 34DB674F1C2B8C1000206663 /* CedarReporters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarReporters.h; sourceTree = ""; }; 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRNil.h; sourceTree = ""; }; 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRNil.m; sourceTree = ""; }; 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRNilSpec.mm; sourceTree = ""; }; 34FD46681B99D43400257186 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS2.0.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; }; 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRTeamCityReporter.h; sourceTree = ""; }; 42064469139B44F600C85605 /* CDRTeamCityReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRTeamCityReporter.m; sourceTree = ""; }; 4523F16026FC3298AB3B00BE /* ExampleWithPublicRunDates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExampleWithPublicRunDates.h; sourceTree = ""; }; 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ExampleWithPublicRunDates.mm; sourceTree = ""; }; 4523F5938DFF8768B6E8902F /* GDataXMLNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDataXMLNode.h; sourceTree = ""; }; 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDataXMLNode.m; sourceTree = ""; }; 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRJUnitXMLReporter.h; sourceTree = ""; }; 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRJUnitXMLReporter.m; sourceTree = ""; }; 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRJUnitXMLReporterSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 5898A53A07BC580786243CD0 /* ConformToSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ConformToSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 5898AADDDCB0B204C88D1199 /* ConformTo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConformTo.mm; sourceTree = ""; }; 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConformTo.h; sourceTree = ""; }; 6628FC8714C4DBA70016652A /* CedarDoubles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarDoubles.h; sourceTree = ""; }; 6628FC9814C4DD440016652A /* CDRSpy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSpy.h; sourceTree = ""; }; 6628FC9B14C4DEC50016652A /* CDRSpy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpy.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 6628FCA014C503530016652A /* Cedar-iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Cedar-iOS.h"; sourceTree = ""; }; 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HaveReceivedSpec.mm; sourceTree = ""; }; 6639A78014C50D3000B564B7 /* HaveReceived.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HaveReceived.h; sourceTree = ""; }; 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpySpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 960118BB1434867E00825FFF /* NSBundle+MainBundleHijack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+MainBundleHijack.m"; sourceTree = ""; }; 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ShouldSyntaxSpec.mm; path = ../ShouldSyntaxSpec.mm; sourceTree = ""; }; 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpecSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSymbolicator.m; sourceTree = ""; }; 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSymbolicator.h; sourceTree = ""; }; 96A07F0813F276640021974D /* Cedar-OSX FocusedSpecs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Cedar-OSX FocusedSpecs"; sourceTree = BUILT_PRODUCTS_DIR; }; 96A07F0A13F276B10021974D /* FocusedSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FocusedSpec.m; path = Focused/FocusedSpec.m; sourceTree = ""; }; 96A07F0E13F27F2F0021974D /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = main.mm; path = Focused/main.mm; sourceTree = ""; }; 96A07F1013F283E40021974D /* FocusedSpec2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FocusedSpec2.m; path = Focused/FocusedSpec2.m; sourceTree = ""; }; 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ObjCHeadersSpec.mm; sourceTree = ""; }; 96B5F9F6144A81A7000A6A5D /* Cedar-iOS HostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-iOS HostApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 96B5FA04144A81A8000A6A5D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 96B5FA06144A81A8000A6A5D /* iOSHostAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iOSHostAppDelegate.h; sourceTree = ""; }; 96B5FA07144A81A8000A6A5D /* iOSHostAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSHostAppDelegate.m; sourceTree = ""; }; 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSymbolicatorSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 96D34480144A82D100352C4A /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DummyView.xib; sourceTree = ""; }; 96D34483144A845100352C4A /* SpecBundleApplicationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = SpecBundleApplicationTests.mm; path = SpecBundle/SpecBundleApplicationTests.mm; sourceTree = ""; }; 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDROTestReporter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRTestBundleRunner.m; sourceTree = ""; }; 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDROTestReporter.h; sourceTree = ""; }; 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRSpecFailureSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 9D28051718E2321D00887CC4 /* ObjectWithValueEquality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectWithValueEquality.h; sourceTree = ""; }; 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectWithValueEquality.m; sourceTree = ""; }; AE02021717452006009A7915 /* StringifiersBase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringifiersBase.mm; sourceTree = ""; }; AE02E7E4184EABCD00414F19 /* Cedar-iOS StaticFrameworkSpecs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-iOS StaticFrameworkSpecs.app"; sourceTree = BUILT_PRODUCTS_DIR; }; AE02E83018526E9F00414F19 /* Cedar-iOSSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = "Cedar-iOSSpec.mm"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE03FBE91B06C33B00013784 /* Cedar-iOS Specs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-iOS Specs.app"; sourceTree = BUILT_PRODUCTS_DIR; }; AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CedarDoubleARCSharedExamples.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE06D87E17AEEE230084D27C /* ObjectWithForwardingTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectWithForwardingTarget.h; sourceTree = ""; }; AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectWithForwardingTarget.m; sourceTree = ""; }; AE0721DF187513870031CC42 /* ExistSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ExistSpec.mm; sourceTree = ""; }; AE0721E2187518FD0031CC42 /* Exist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exist.h; sourceTree = ""; }; AE0AF55E13E9C0E300029396 /* CedarMatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarMatchers.h; sourceTree = ""; }; AE0AF57913E9C16D00029396 /* MatcherTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatcherTemplate.h; sourceTree = ""; }; AE0AF58413E9E87E00029396 /* ActualValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActualValue.h; sourceTree = ""; }; AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockMatcher_ARCSpecSpec.mm; sourceTree = ""; }; AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CDRSpec+XCTestSupport.m"; sourceTree = ""; }; AE0F354619E7059200B9F116 /* OSXGeometryCompareEqual.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSXGeometryCompareEqual.h; sourceTree = ""; }; AE0F354819E705C700B9F116 /* OSXGeometryStringifiers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSXGeometryStringifiers.h; sourceTree = ""; }; AE0F354A19E7073B00B9F116 /* OSXGeometryEqualSpecSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSXGeometryEqualSpecSpec.mm; sourceTree = ""; }; AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompareCloseTo.h; sourceTree = ""; }; AE167EF115B216DA005960B9 /* RaiseException.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RaiseException.mm; sourceTree = ""; }; AE18A7D213F45BE500C8872C /* ComparatorsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComparatorsBase.h; sourceTree = ""; }; AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComparatorsContainer.h; sourceTree = ""; }; AE18A7FA13F4601400C8872C /* Contain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Contain.h; sourceTree = ""; }; AE18A80913F4640600C8872C /* ContainSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ContainSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE248F9819DCD52500092C14 /* Cedar-OSX HostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-OSX HostApp.app"; sourceTree = BUILT_PRODUCTS_DIR; }; AE248F9B19DCD52500092C14 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; AE248F9C19DCD52500092C14 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; AE248FAA19DCD52500092C14 /* Cedar-OSX SpecBundle.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cedar-OSX SpecBundle.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRXCTestSuite.h; sourceTree = ""; }; AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRXCTestSuite.m; sourceTree = ""; }; AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRXCTestSuiteSpec.mm; sourceTree = ""; }; AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRXCTestCase.h; sourceTree = ""; }; AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRXCTestCase.m; sourceTree = ""; }; AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CedarDouble.mm; sourceTree = ""; }; AE3E8F35184FEEE000633740 /* ObjectWithCollections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectWithCollections.h; sourceTree = ""; }; AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectWithCollections.m; sourceTree = ""; }; AE4864F81B067620005DB302 /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AE4A9457187F7D8F008566F5 /* BeFalsy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeFalsy.h; sourceTree = ""; }; AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeFalsySpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE4A945D1880792E008566F5 /* RejectedMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RejectedMethod.h; sourceTree = ""; }; AE4A946018807DA6008566F5 /* RejectedMethod.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RejectedMethod.mm; sourceTree = ""; }; AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSInvocation+CDRXExample.h"; sourceTree = ""; }; AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSInvocation+CDRXExample.m"; sourceTree = ""; }; AE5218D1175979CA00A656BC /* ObjectWithWeakDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectWithWeakDelegate.h; sourceTree = ""; }; AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectWithWeakDelegate.m; sourceTree = ""; }; AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WeakReferenceCompatibilitySpec.mm; sourceTree = ""; }; AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRRuntimeUtilities.m; sourceTree = ""; }; AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CDRRuntimeUtilities.h; sourceTree = ""; }; AE597B4015B0638B00EEF305 /* InvocationMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InvocationMatcher.h; sourceTree = ""; }; AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeGreaterThanSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE71E7CA175E958F002A54D5 /* ARCViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARCViewController.h; sourceTree = ""; }; AE71E7CB175E958F002A54D5 /* ARCViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARCViewController.m; sourceTree = ""; }; AE74902E15B45E80008EA127 /* CDRProtocolFake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRProtocolFake.h; sourceTree = ""; }; AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRProtocolFakeSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE74906E15B48690008EA127 /* CDRProtocolFake.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRProtocolFake.mm; sourceTree = ""; }; AE74907015B486CD008EA127 /* CDRFake.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRFake.mm; sourceTree = ""; }; AE74907315B488BE008EA127 /* CDRFake.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CDRFake.h; sourceTree = ""; }; AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CedarApplicationDelegateSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSInvocation+Cedar.m"; path = "Source/Extensions/NSInvocation+Cedar.m"; sourceTree = SOURCE_ROOT; }; AE807887183C71950078C608 /* ArgumentReleaser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentReleaser.h; sourceTree = ""; }; AE807888183C71950078C608 /* ArgumentReleaser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArgumentReleaser.m; sourceTree = ""; }; AE807889183C71950078C608 /* SimpleIncrementer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleIncrementer.h; sourceTree = ""; }; AE80788A183C71950078C608 /* SimpleIncrementer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleIncrementer.m; sourceTree = ""; }; AE80788B183C71950078C608 /* SimpleKeyValueObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleKeyValueObserver.h; sourceTree = ""; }; AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SimpleKeyValueObserver.m; sourceTree = ""; }; AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShouldSyntax.h; sourceTree = ""; }; AE8C87AA13624523006C9305 /* ExpectFailureWithMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExpectFailureWithMessage.h; sourceTree = ""; }; AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ExpectFailureWithMessage.mm; sourceTree = ""; }; AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSpecFailure.h; sourceTree = ""; }; AE8F1D901850F6C00059E840 /* CedarObservedObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CedarObservedObject.h; sourceTree = ""; }; AE8F9C141B795A7C00B956C5 /* ContainSubset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContainSubset.h; sourceTree = ""; }; AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnyInstanceArgument.h; sourceTree = ""; }; AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AnyInstanceArgument.mm; sourceTree = ""; }; AE9AA67915AB72DA00617E1A /* CDRClassFake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRClassFake.h; sourceTree = ""; }; AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRClassFakeSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRClassFake.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE9AA68815AC728A00617E1A /* CedarDouble.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CedarDouble.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CedarDoubleSharedExamples.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AE9AA6D115AE082500617E1A /* StubbedMethod.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StubbedMethod.h; sourceTree = ""; }; AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarDoubleImpl.h; sourceTree = ""; }; AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CedarDoubleImpl.mm; sourceTree = ""; }; AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSInvocation+Cedar.h"; sourceTree = ""; }; AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMethodSignature+Cedar.h"; sourceTree = ""; }; AEB1A74115F304A9002E4167 /* StubbedMethod.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StubbedMethod.mm; sourceTree = ""; }; AEB45A901496C8D800845D09 /* RaiseException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RaiseException.h; sourceTree = ""; }; AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RaiseExceptionSpec.mm; sourceTree = ""; }; AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRDefaultReporterSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIGeometryCompareEqual.h; sourceTree = ""; }; AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIGeometryStringifiers.h; sourceTree = ""; }; AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UIKitEqualSpec.mm; sourceTree = ""; }; AEC40C57174ACAD900474D2D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; AEC7873715F440980058A27B /* InvocationMatcher.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InvocationMatcher.mm; sourceTree = ""; }; AEC7874C15F444A50058A27B /* HaveReceived.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HaveReceived.mm; sourceTree = ""; }; AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRColorizedReporter.h; sourceTree = ""; }; AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRColorizedReporter.m; sourceTree = ""; }; AECF136015D1425C003AAB9C /* Argument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Argument.h; sourceTree = ""; }; AECF136315D14274003AAB9C /* ValueArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueArgument.h; sourceTree = ""; }; AECF136615D142E3003AAB9C /* ReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReturnValue.h; sourceTree = ""; }; AECF136915D1439B003AAB9C /* AnyArgument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnyArgument.h; sourceTree = ""; }; AED10EBA18F46C0E00950904 /* FooSuperclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FooSuperclass.h; sourceTree = ""; }; AED10EBB18F46C0E00950904 /* FooSuperclass.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FooSuperclass.m; sourceTree = ""; }; AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CedarNiceFakeSharedExamples.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CedarOrdinaryFakeSharedExamples.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSpyInfo.h; sourceTree = ""; }; AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRSpyInfo.mm; sourceTree = ""; }; AEEE1FB611DC271300029872 /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AEEE1FB811DC271300029872 /* Cedar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Cedar-Info.plist"; sourceTree = ""; }; AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRDefaultReporter.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FC511DC27B800029872 /* CDRExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExample.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FC611DC27B800029872 /* CDRExampleBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleBase.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleGroup.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FC811DC27B800029872 /* CDRFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRFunctions.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FC911DC27B800029872 /* CDRSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRSpec.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRDefaultReporter.h; sourceTree = ""; }; AEEE1FCC11DC27B800029872 /* CDRExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExample.h; sourceTree = ""; }; AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CDRExampleBase.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleGroup.h; sourceTree = ""; }; AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleParent.h; sourceTree = ""; }; AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleReporter.h; sourceTree = ""; }; AEEE1FD111DC27B800029872 /* CDRFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRFunctions.h; sourceTree = ""; }; AEEE1FD211DC27B800029872 /* CDRSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CDRSpec.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FD311DC27B800029872 /* Cedar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cedar.h; sourceTree = ""; }; AEEE1FDA11DC27B800029872 /* CedarApplicationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarApplicationDelegate.h; sourceTree = ""; }; AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CDRSpecHelper.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CedarApplicationDelegate.m; sourceTree = ""; }; AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRSpecHelper.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleGroupSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEEE1FED11DC27B800029872 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; AEEE1FEF11DC27B800029872 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRHooksSpec.mm; sourceTree = ""; }; AEEE1FF111DC27B800029872 /* SpecSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SpecSpec.mm; sourceTree = ""; }; AEEE1FF211DC27B800029872 /* SpecSpec2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpecSpec2.m; sourceTree = ""; }; AEEE218611DC28E200029872 /* Cedar-OSX Specs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Cedar-OSX Specs"; sourceTree = BUILT_PRODUCTS_DIR; }; AEEE222211DC2A1400029872 /* Rakefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Rakefile; sourceTree = ""; }; AEEE222311DC2A1400029872 /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.markdown; sourceTree = ""; }; AEEE222911DC2B0600029872 /* libCedar.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCedar.a; sourceTree = BUILT_PRODUCTS_DIR; }; AEEE227611DC2CF900029872 /* Cedar-iOS StaticLib Specs.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cedar-iOS StaticLib Specs.app"; sourceTree = BUILT_PRODUCTS_DIR; }; AEEF360619DE21DB00794484 /* CDRSpecFailure.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpecFailure.m; sourceTree = ""; }; AEEF360D19DF24AB00794484 /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = ""; }; AEEF360F19DF27E400794484 /* edward.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = edward.jpg; sourceTree = ""; }; AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeGreaterThan.h; sourceTree = ""; }; AEF32FF3145A2E91002F93BB /* CompareEqual.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompareEqual.h; sourceTree = ""; }; AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompareGreaterThan.h; sourceTree = ""; }; AEF33008145B4E3B002F93BB /* BeGTESpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeGTESpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF3300B145B4F75002F93BB /* BeGTE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeGTE.h; sourceTree = ""; }; AEF33012145B6188002F93BB /* BeLessThanSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeLessThanSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF33016145B6222002F93BB /* BeLessThan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeLessThan.h; sourceTree = ""; }; AEF3301D145B68D7002F93BB /* BeLTESpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeLTESpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF33020145B69DE002F93BB /* BeLTE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeLTE.h; sourceTree = ""; }; AEF52C26187F236D00C8D2D8 /* SimpleMultiplier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleMultiplier.h; sourceTree = ""; }; AEF72F7713EC730700786282 /* CedarComparators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarComparators.h; sourceTree = ""; }; AEF72F7A13EC734000786282 /* CedarStringifiers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarStringifiers.h; sourceTree = ""; }; AEF72FFB13ECC21E00786282 /* Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base.h; sourceTree = ""; }; AEF72FFC13ECC21E00786282 /* BeCloseTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeCloseTo.h; sourceTree = ""; }; AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeInstanceOf.h; sourceTree = ""; }; AEF72FFE13ECC21E00786282 /* BeNil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeNil.h; sourceTree = ""; }; AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeSameInstanceAs.h; sourceTree = ""; }; AEF7300013ECC21E00786282 /* BeTruthy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeTruthy.h; sourceTree = ""; }; AEF7300113ECC21E00786282 /* Equal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Equal.h; sourceTree = ""; }; AEF7301013ECC25000786282 /* BeEmpty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeEmpty.h; sourceTree = ""; }; AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeCloseToSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeInstanceOfSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7301613ECC4AE00786282 /* BeNilSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeNilSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeSameInstanceAsSpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeTruthySpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7301913ECC4AE00786282 /* EqualSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EqualSpec.mm; sourceTree = ""; }; AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MutableEqualSpec.mm; sourceTree = ""; }; AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = BeEmptySpec.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; AEF7303813ECCB7B00786282 /* StringifiersBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringifiersBase.h; sourceTree = ""; }; AEF7303913ECCB7B00786282 /* StringifiersContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringifiersContainer.h; sourceTree = ""; }; AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRVersion.h; sourceTree = ""; }; AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRSharedExampleGroupPool.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSharedExampleGroupPool.h; sourceTree = ""; }; AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ComparatorsContainerConvenience.h; sourceTree = ""; }; CA17998C17F89C4B00C38060 /* RespondTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RespondTo.h; sourceTree = ""; }; CA17998F17F89C9700C38060 /* RespondTo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RespondTo.mm; sourceTree = ""; }; CA17999217F8A0EE00C38060 /* RespondToSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RespondToSpec.mm; sourceTree = ""; }; E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRSlowTestStatistics.h; sourceTree = ""; }; E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSlowTestStatistics.m; sourceTree = ""; }; E32861301604F287001FA77E /* FibonacciCalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FibonacciCalculator.h; sourceTree = ""; }; E32861311604F287001FA77E /* FibonacciCalculator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FibonacciCalculator.m; sourceTree = ""; }; E4BCFDD01817FA110083ED98 /* ObjectWithProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectWithProperty.h; sourceTree = ""; }; E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjectWithProperty.m; sourceTree = ""; }; F71C2F321D3DAD71003B37DC /* CedarTestSpecBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarTestSpecBuilder.h; sourceTree = ""; }; F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CedarTestSpecBuilder.m; sourceTree = ""; }; F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContainSubsetSpec.mm; sourceTree = ""; }; F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRSpecRunSpec.mm; sourceTree = ""; }; F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CDRStateTracking.h; path = ../../CDRStateTracking.h; sourceTree = ""; }; F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CDRStateTracker.h; path = ../../CDRStateTracker.h; sourceTree = ""; }; F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CDRStateTracker.m; sourceTree = ""; }; F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRRunState.h; sourceTree = ""; }; F7C9BC001D45E16200B694C0 /* CDRRunState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRRunState.m; sourceTree = ""; }; F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRXCTestObserver.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 1F45A3D2180E4796003C1E36 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 346D1AA81BBC406700BECD4B /* libCedar.a in Frameworks */, 1F45A3D4180E4796003C1E36 /* UIKit.framework in Frameworks */, 1F45A3D5180E4796003C1E36 /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 346262811B99C1DC002CAEBD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 34A848581B9A4A0500396A09 /* UIKit.framework in Frameworks */, 34FD466A1B99D43F00257186 /* libxml2.tbd in Frameworks */, 34FD462A1B99D13C00257186 /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 34852D171BBE35FF0072D249 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 34852D181BBE35FF0072D249 /* UIKit.framework in Frameworks */, 34852D191BBE35FF0072D249 /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 34D7C4661BB9B71600E8E523 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 34D7C4B81BB9CB5700E8E523 /* libxml2.tbd in Frameworks */, 34D7C4B61BB9CB4B00E8E523 /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 96A07F0213F276640021974D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 96A07F0413F276640021974D /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 96B5F9F3144A81A7000A6A5D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( AEC40C58174ACAD900474D2D /* UIKit.framework in Frameworks */, 96B5F9FC144A81A7000A6A5D /* CoreGraphics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AE02E7E1184EABCD00414F19 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( AE02E7E6184EABCD00414F19 /* CoreGraphics.framework in Frameworks */, AE02E7E7184EABCD00414F19 /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AE03FBE61B06C33B00013784 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 346D1A9F1BBB408F00BECD4B /* CoreGraphics.framework in Frameworks */, 346D1A9C1BBB405600BECD4B /* UIKit.framework in Frameworks */, AE03FC0F1B06C37E00013784 /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AE248F9519DCD52500092C14 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; AE248FA719DCD52500092C14 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( AE248FB819DCD54600092C14 /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE218411DC28E200029872 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 342FB2C71BC328320090E253 /* ApplicationServices.framework in Frameworks */, 342FB2C51BC326100090E253 /* CoreGraphics.framework in Frameworks */, 346D1AAA1BBC41FE00BECD4B /* Foundation.framework in Frameworks */, AEEE220311DC29AC00029872 /* Cedar.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE227411DC2CF900029872 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 346D1AAD1BBC46B600BECD4B /* QuartzCore.framework in Frameworks */, AEEE227E11DC2D3A00029872 /* libCedar.a in Frameworks */, 346D1A9E1BBB408E00BECD4B /* CoreGraphics.framework in Frameworks */, 346D1A9B1BBB404800BECD4B /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 1FE15C171869071B00207F0C /* Reporters */ = { isa = PBXGroup; children = ( AEC9DEEB12C2CC7E0039512D /* CDRColorizedReporter.m */, AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */, 492951DF1481AAFA00FA8916 /* CDRJUnitXMLReporter.m */, 96EA1CA6142C6425001A78E0 /* CDROTestReporter.m */, 1FE15C1A1869091900207F0C /* CDRReportDispatcher.m */, 42064469139B44F600C85605 /* CDRTeamCityReporter.m */, 1FF449B018A0C03800AF94B0 /* CDRBufferedDefaultReporter.m */, ); path = Reporters; sourceTree = ""; }; 1FE15C241869092300207F0C /* Reporters */ = { isa = PBXGroup; children = ( AEC9DEEA12C2CC7E0039512D /* CDRColorizedReporter.h */, AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */, AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */, 492951DC1481AAB100FA8916 /* CDRJUnitXMLReporter.h */, 96EA1CAC142C6449001A78E0 /* CDROTestReporter.h */, 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */, 1FF449B318A0C04D00AF94B0 /* CDRBufferedDefaultReporter.h */, 34DB674F1C2B8C1000206663 /* CedarReporters.h */, ); path = Reporters; sourceTree = ""; }; 1FE15C25186919F400207F0C /* Reporters */ = { isa = PBXGroup; children = ( AEBCDD7E173ACD6700B42B58 /* CDRDefaultReporterSpec.mm */, 492951E31482FF6200FA8916 /* CDRJUnitXMLReporterSpec.mm */, 1F47B9A6186D69CD005A8CE1 /* CDROTestReporterSpec.mm */, ); path = Reporters; sourceTree = ""; }; 34157D121B75A1D1007AD1BA /* Public */ = { isa = PBXGroup; children = ( 66F00B4F14C4D8F600146D88 /* Doubles */, AEEE1FD411DC27B800029872 /* iOS */, AE0AF55D13E9C06900029396 /* Matchers */, 1FE15C241869092300207F0C /* Reporters */, AEEE1FCC11DC27B800029872 /* CDRExample.h */, AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */, AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */, AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */, AEEE1FD111DC27B800029872 /* CDRFunctions.h */, 2234907C18009DA6001C8E8D /* CDRHooks.h */, 34C95F4F1C2DD7B30055F089 /* CDRNullabilityCompat.h */, AEFD17B311DD1E8200F4448A /* CDRSharedExampleGroupPool.h */, AEEE1FD211DC27B800029872 /* CDRSpec.h */, AE8C880E13626FA5006C9305 /* CDRSpecFailure.h */, AEEE1FDB11DC27B800029872 /* CDRSpecHelper.h */, AEF8FB0619E6000E00DD4FE4 /* CDRVersion.h */, AEEE1FD311DC27B800029872 /* Cedar.h */, ); path = Public; sourceTree = ""; }; 34157D131B75A1D7007AD1BA /* Project */ = { isa = PBXGroup; children = ( 34157D141B75A1EE007AD1BA /* Doubles */, 34157D151B75A1F7007AD1BA /* Extensions */, 34157D161B75A200007AD1BA /* ReporterHelpers */, 34157D171B75A20B007AD1BA /* Reporters */, 34157D181B75A212007AD1BA /* XCTest */, 3460489318F2DBBF00BC93B6 /* CDRBlockHelper.h */, 34F3DF7B1A6ABA2E003041DA /* CDRNil.h */, 34777EB61B99451200A69FCF /* CDRPrivateFunctions.h */, AE55BF1D19A7CF83005948E6 /* CDRRuntimeUtilities.h */, F7C9BBFF1D45E16200B694C0 /* CDRRunState.h */, F7C9BBF41D3E85A100B694C0 /* CDRStateTracker.h */, 3492DA9D1BA6F9E70032B35A /* CDRSpecRun.h */, F7C9BBF31D3E851100B694C0 /* CDRStateTracking.h */, 969B6F95160F1FEC00C7C792 /* CDRSymbolicator.h */, 34681C2D18FE4611009D38AC /* CDRTypeUtilities.h */, ); path = Project; sourceTree = ""; }; 34157D141B75A1EE007AD1BA /* Doubles */ = { isa = PBXGroup; children = ( AEE8DBD2175FFCF3008AF18A /* CDRSpyInfo.h */, AE9AA6DA15AE0B0300617E1A /* CedarDoubleImpl.h */, ); path = Doubles; sourceTree = ""; }; 34157D151B75A1F7007AD1BA /* Extensions */ = { isa = PBXGroup; children = ( AEAA191019DCC5A900194E95 /* NSInvocation+Cedar.h */, AEAA191119DCC5A900194E95 /* NSMethodSignature+Cedar.h */, ); path = Extensions; sourceTree = ""; }; 34157D161B75A200007AD1BA /* ReporterHelpers */ = { isa = PBXGroup; children = ( 1F483E30187D39D000521F81 /* CDROTestNamer.h */, E31179D0161FD937007D3CDE /* CDRSlowTestStatistics.h */, ); path = ReporterHelpers; sourceTree = ""; }; 34157D171B75A20B007AD1BA /* Reporters */ = { isa = PBXGroup; children = ( 1FE15C191869091900207F0C /* CDRReportDispatcher.h */, ); path = Reporters; sourceTree = ""; }; 34157D181B75A212007AD1BA /* XCTest */ = { isa = PBXGroup; children = ( AE34724919C37ECF005CA6F1 /* CDRXCTestCase.h */, 34322B081BA740B900D0CFBD /* CDRXCTestObserver.h */, AE31A29D19C0F23F00C438C1 /* CDRXCTestSuite.h */, 3492DA9A1BA672A60032B35A /* CDRXCTestSupport.h */, AE4E9B9019C8B44700D794CE /* NSInvocation+CDRXExample.h */, ); path = XCTest; sourceTree = ""; }; 346262791B99C1DB002CAEBD /* watchOS */ = { isa = PBXGroup; children = ( 3462628D1B99C1DC002CAEBD /* ExtensionDelegate.mm */, 34A848551B9A491E00396A09 /* Interface.storyboard */, 3462627F1B99C1DB002CAEBD /* App-Info.plist */, 346262911B99C1DC002CAEBD /* Extension-Info.plist */, ); path = watchOS; sourceTree = ""; }; 346D1AA01BBB445B00BECD4B /* SpecBundle */ = { isa = PBXGroup; children = ( 346D1AA11BBB448800BECD4B /* Support */, AE248F9919DCD52500092C14 /* OS X Host App */, 96B5F9FD144A81A7000A6A5D /* iOS Host App */, ); path = SpecBundle; sourceTree = ""; }; 346D1AA11BBB448800BECD4B /* Support */ = { isa = PBXGroup; children = ( 34757E201BA466050047BC8D /* TestObservationHelper.h */, 34757E211BA466050047BC8D /* TestObservationHelper.m */, ); path = Support; sourceTree = ""; }; 34A8485A1B9A4D9800396A09 /* iOS */ = { isa = PBXGroup; children = ( 34D4B5C418F3B68900FB2C3B /* UIKitComparatorsContainer.h */, ); path = iOS; sourceTree = ""; }; 34DB67471C2B4CBA00206663 /* Swift */ = { isa = PBXGroup; children = ( 34DB67481C2B4D6A00206663 /* SwiftSpec.swift */, 345B1E8D1C31DA2B009BB77D /* XCTAssertSpec.swift */, 345B1E881C31CC96009BB77D /* Spec-Bridging-Header.h */, ); path = Swift; sourceTree = ""; }; 4523FFB9BD607306C7ED94A3 /* GData */ = { isa = PBXGroup; children = ( 4523FB751BC9186566CE8E10 /* GDataXMLNode.m */, 4523F5938DFF8768B6E8902F /* GDataXMLNode.h */, ); path = GData; sourceTree = ""; }; 6628FC8414C4DAB90016652A /* Doubles */ = { isa = PBXGroup; children = ( AE94D04215F3447200A0C2B7 /* Arguments */, AE74906E15B48690008EA127 /* CDRProtocolFake.mm */, 6628FC9B14C4DEC50016652A /* CDRSpy.mm */, AE9AA68315AB78FB00617E1A /* CDRClassFake.mm */, AE9AA6DD15AE0BE200617E1A /* CedarDoubleImpl.mm */, AE74907015B486CD008EA127 /* CDRFake.mm */, AE36AC6415B5CA6E00EB6C51 /* CedarDouble.mm */, AE4A946018807DA6008566F5 /* RejectedMethod.mm */, AEB1A74115F304A9002E4167 /* StubbedMethod.mm */, AEC7873715F440980058A27B /* InvocationMatcher.mm */, AEC7874C15F444A50058A27B /* HaveReceived.mm */, AEE8DBD3175FFCF3008AF18A /* CDRSpyInfo.mm */, ); path = Doubles; sourceTree = ""; }; 66F00B4F14C4D8F600146D88 /* Doubles */ = { isa = PBXGroup; children = ( AECF135E15D1421A003AAB9C /* Arguments */, AE74902E15B45E80008EA127 /* CDRProtocolFake.h */, 6628FC8714C4DBA70016652A /* CedarDoubles.h */, 6628FC9814C4DD440016652A /* CDRSpy.h */, AE9AA67915AB72DA00617E1A /* CDRClassFake.h */, 6639A78014C50D3000B564B7 /* HaveReceived.h */, AE9AA68815AC728A00617E1A /* CedarDouble.h */, AE4A945D1880792E008566F5 /* RejectedMethod.h */, AE9AA6D115AE082500617E1A /* StubbedMethod.h */, AE597B4015B0638B00EEF305 /* InvocationMatcher.h */, AE74907315B488BE008EA127 /* CDRFake.h */, ); path = Doubles; sourceTree = ""; }; 66F00B5014C4D92500146D88 /* Doubles */ = { isa = PBXGroup; children = ( AE9AA67F15AB748E00617E1A /* CDRClassFakeSpec.mm */, AE74903015B45E9D008EA127 /* CDRProtocolFakeSpec.mm */, 66F00B5114C4D97C00146D88 /* CDRSpySpec.mm */, AE0695F217A1885A0053E59A /* CedarDoubleARCSharedExamples.mm */, AE9AA69615ADB99800617E1A /* CedarDoubleSharedExamples.mm */, AEE0665517315C20003CA143 /* CedarNiceFakeSharedExamples.mm */, AEE0665817315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm */, 6639A77A14C509FE00B564B7 /* HaveReceivedSpec.mm */, ); path = Doubles; sourceTree = ""; }; 96A07F0D13F27ED70021974D /* Focused */ = { isa = PBXGroup; children = ( 96A07F0A13F276B10021974D /* FocusedSpec.m */, 96A07F1013F283E40021974D /* FocusedSpec2.m */, 96A07F0E13F27F2F0021974D /* main.mm */, ); name = Focused; sourceTree = ""; }; 96B5F9FD144A81A7000A6A5D /* iOS Host App */ = { isa = PBXGroup; children = ( 96B5FA06144A81A8000A6A5D /* iOSHostAppDelegate.h */, 96B5FA07144A81A8000A6A5D /* iOSHostAppDelegate.m */, 96D3447F144A82D100352C4A /* DummyView.xib */, 96B5FA04144A81A8000A6A5D /* main.m */, 34852D251BBE38EE0072D249 /* Default-568h@2x.png */, ); path = "iOS Host App"; sourceTree = ""; }; AE02021617451FBD009A7915 /* Stringifiers */ = { isa = PBXGroup; children = ( AE02021717452006009A7915 /* StringifiersBase.mm */, ); path = Stringifiers; sourceTree = ""; }; AE0AF55D13E9C06900029396 /* Matchers */ = { isa = PBXGroup; children = ( AE0F354519E7057900B9F116 /* OSX */, AEF72FFA13ECC19200786282 /* Base */, AEF72FF913ECC16400786282 /* Container */, AEF7302E13ECC6EE00786282 /* Stringifiers */, AE18A7D113F45BBE00C8872C /* Comparators */, AEC40C4D174AC4C000474D2D /* UIKit */, AE0AF58413E9E87E00029396 /* ActualValue.h */, AE0AF55E13E9C0E300029396 /* CedarMatchers.h */, AEF72F7713EC730700786282 /* CedarComparators.h */, AEF72F7A13EC734000786282 /* CedarStringifiers.h */, AE0AF57913E9C16D00029396 /* MatcherTemplate.h */, AE84F0DA145B70DD00769F85 /* ShouldSyntax.h */, ); path = Matchers; sourceTree = ""; }; AE0C9D8919C0C61300B4DD2B /* XCTest */ = { isa = PBXGroup; children = ( AE0C9D8B19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m */, AE34724A19C37ECF005CA6F1 /* CDRXCTestCase.m */, AE31A29E19C0F23F00C438C1 /* CDRXCTestSuite.m */, F7F409971B2E3C8B001EFA14 /* CDRXCTestObserver.m */, AE4E9B9119C8B44700D794CE /* NSInvocation+CDRXExample.m */, 3492DA961BA670C10032B35A /* CDRXCTestFunctions.m */, ); path = XCTest; sourceTree = ""; }; AE0F354519E7057900B9F116 /* OSX */ = { isa = PBXGroup; children = ( AE0F354619E7059200B9F116 /* OSXGeometryCompareEqual.h */, AE0F354819E705C700B9F116 /* OSXGeometryStringifiers.h */, ); path = OSX; sourceTree = ""; }; AE0F354919E7071A00B9F116 /* OSX */ = { isa = PBXGroup; children = ( AE0F354A19E7073B00B9F116 /* OSXGeometryEqualSpecSpec.mm */, ); path = OSX; sourceTree = ""; }; AE167EEC15B210C9005960B9 /* Matchers */ = { isa = PBXGroup; children = ( AE02021617451FBD009A7915 /* Stringifiers */, AE167EF015B216A5005960B9 /* Base */, ); path = Matchers; sourceTree = ""; }; AE167EF015B216A5005960B9 /* Base */ = { isa = PBXGroup; children = ( AE167EF115B216DA005960B9 /* RaiseException.mm */, CA17998F17F89C9700C38060 /* RespondTo.mm */, 5898AADDDCB0B204C88D1199 /* ConformTo.mm */, ); path = Base; sourceTree = ""; }; AE18A7D113F45BBE00C8872C /* Comparators */ = { isa = PBXGroup; children = ( AE18A7D213F45BE500C8872C /* ComparatorsBase.h */, AE18A7D513F45BFC00C8872C /* ComparatorsContainer.h */, AEF32FF3145A2E91002F93BB /* CompareEqual.h */, AEF32FF7145A2EDF002F93BB /* CompareGreaterThan.h */, AEFF375718FC452E002DA993 /* ComparatorsContainerConvenience.h */, AE0F354D19E87D6F00B9F116 /* CompareCloseTo.h */, ); path = Comparators; sourceTree = ""; }; AE248F9919DCD52500092C14 /* OS X Host App */ = { isa = PBXGroup; children = ( AE248F9B19DCD52500092C14 /* Info.plist */, AE248F9C19DCD52500092C14 /* main.m */, ); path = "OS X Host App"; sourceTree = ""; }; AE34723F19C2257A005CA6F1 /* XCTest */ = { isa = PBXGroup; children = ( AE34724019C2259B005CA6F1 /* CDRXCTestSuiteSpec.mm */, ); path = XCTest; sourceTree = ""; }; AE7F170317272FB000E1146D /* Extensions */ = { isa = PBXGroup; children = ( AE7F1705172730B000E1146D /* NSInvocation+Cedar.m */, 34ADE41618F23C8E00BD1E99 /* NSMethodSignature+Cedar.m */, ); path = Extensions; sourceTree = ""; }; AE8C879F1362068A006C9305 /* Matchers */ = { isa = PBXGroup; children = ( AEF7301313ECC4AE00786282 /* Base */, AEF7302913ECC4C100786282 /* Container */, AE8C87AA13624523006C9305 /* ExpectFailureWithMessage.h */, AE8C87AB13624524006C9305 /* ExpectFailureWithMessage.mm */, AE0F354919E7071A00B9F116 /* OSX */, 966E74EC145A6CA0002E8D49 /* ShouldSyntaxSpec.mm */, AEC40C52174AC51800474D2D /* UIKit */, ); path = Matchers; sourceTree = ""; }; AE94D04215F3447200A0C2B7 /* Arguments */ = { isa = PBXGroup; children = ( AE94D04315F3449500A0C2B7 /* AnyInstanceArgument.mm */, 1FF4497C18A0B37A00AF94B0 /* AnyArgument.mm */, 34ADD2DE1921F18100B057AC /* AnyInstanceOfClassArgument.mm */, 34ADD2E51921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm */, ); path = Arguments; sourceTree = ""; }; AEC40C4D174AC4C000474D2D /* UIKit */ = { isa = PBXGroup; children = ( 34A8485A1B9A4D9800396A09 /* iOS */, AEC40C4E174AC4C000474D2D /* UIGeometryCompareEqual.h */, AEC40C4F174AC4C000474D2D /* UIGeometryStringifiers.h */, ); path = UIKit; sourceTree = ""; }; AEC40C52174AC51800474D2D /* UIKit */ = { isa = PBXGroup; children = ( AEC40C53174AC51800474D2D /* UIKitEqualSpec.mm */, 34D4B5C118F3ADFF00FB2C3B /* UIKitContainSpec.mm */, ); path = UIKit; sourceTree = ""; }; AECF135E15D1421A003AAB9C /* Arguments */ = { isa = PBXGroup; children = ( AECF136015D1425C003AAB9C /* Argument.h */, AECF136315D14274003AAB9C /* ValueArgument.h */, AE94D03E15F341B200A0C2B7 /* AnyInstanceArgument.h */, AECF136615D142E3003AAB9C /* ReturnValue.h */, AECF136915D1439B003AAB9C /* AnyArgument.h */, 34ADD2DD1921F0B500B057AC /* AnyInstanceOfClassArgument.h */, 34ADD2E41921F2F600B057AC /* AnyInstanceConformingToProtocolArgument.h */, ); path = Arguments; sourceTree = ""; }; AEEE1FA411DC26EA00029872 = { isa = PBXGroup; children = ( AEEE1FC311DC27B800029872 /* Source */, AEEE1FE711DC27B800029872 /* Spec */, AEEE202611DC286500029872 /* Frameworks */, AEEE1FB711DC271300029872 /* Products */, AEEE1FB811DC271300029872 /* Cedar-Info.plist */, AEEE222211DC2A1400029872 /* Rakefile */, AEEE222311DC2A1400029872 /* README.markdown */, ); sourceTree = ""; }; AEEE1FB711DC271300029872 /* Products */ = { isa = PBXGroup; children = ( AEEE1FB611DC271300029872 /* Cedar.framework */, AEEE218611DC28E200029872 /* Cedar-OSX Specs */, AEEE222911DC2B0600029872 /* libCedar.a */, AEEE227611DC2CF900029872 /* Cedar-iOS StaticLib Specs.app */, 96A07F0813F276640021974D /* Cedar-OSX FocusedSpecs */, 96B5F9F6144A81A7000A6A5D /* Cedar-iOS HostApp.app */, 1F45A3DD180E4796003C1E36 /* Cedar-iOS SpecBundle.xctest */, AE02E7E4184EABCD00414F19 /* Cedar-iOS StaticFrameworkSpecs.app */, AE248F9819DCD52500092C14 /* Cedar-OSX HostApp.app */, AE248FAA19DCD52500092C14 /* Cedar-OSX SpecBundle.xctest */, AE4864F81B067620005DB302 /* Cedar.framework */, AE03FBE91B06C33B00013784 /* Cedar-iOS Specs.app */, 346261DF1B995239002CAEBD /* Cedar.framework */, 346262781B99C1DB002CAEBD /* Cedar-watchOS Specs.app */, 346262841B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex */, 34D7C3CA1BB9747400E8E523 /* Cedar.framework */, 34D7C4691BB9B71600E8E523 /* Cedar-tvOS SpecBundle.xctest */, 34852D211BBE35FF0072D249 /* Cedar-watchOS HostApp.app */, ); name = Products; sourceTree = ""; }; AEEE1FC311DC27B800029872 /* Source */ = { isa = PBXGroup; children = ( 6628FC8414C4DAB90016652A /* Doubles */, AE7F170317272FB000E1146D /* Extensions */, AEEE1FCA11DC27B800029872 /* Headers */, AEEE1FDC11DC27B800029872 /* iOS */, AE167EEC15B210C9005960B9 /* Matchers */, E31179CE161FD90C007D3CDE /* ReporterHelpers */, 1FE15C171869071B00207F0C /* Reporters */, AE0C9D8919C0C61300B4DD2B /* XCTest */, AEEE1FC511DC27B800029872 /* CDRExample.m */, AEEE1FC611DC27B800029872 /* CDRExampleBase.m */, AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */, AEEE1FC811DC27B800029872 /* CDRFunctions.m */, 34F3DF7C1A6ABA2E003041DA /* CDRNil.m */, AE55BF1A19A7CF58005948E6 /* CDRRuntimeUtilities.m */, AEFD17B111DD1E7200F4448A /* CDRSharedExampleGroupPool.m */, AEEE1FC911DC27B800029872 /* CDRSpec.m */, AEEF360619DE21DB00794484 /* CDRSpecFailure.m */, AEEE1FE611DC27B800029872 /* CDRSpecHelper.m */, 3492DA9E1BA6F9E70032B35A /* CDRSpecRun.m */, F7C9BC001D45E16200B694C0 /* CDRRunState.m */, F7C9BBF51D3E85A100B694C0 /* CDRStateTracker.m */, 969B6F82160C61E000C7C792 /* CDRSymbolicator.m */, 96EA1CA7142C6425001A78E0 /* CDRTestBundleRunner.m */, 34681C2B18FE451E009D38AC /* CDRTypeUtilities.m */, ); path = Source; sourceTree = ""; }; AEEE1FCA11DC27B800029872 /* Headers */ = { isa = PBXGroup; children = ( 34157D131B75A1D7007AD1BA /* Project */, 34157D121B75A1D1007AD1BA /* Public */, ); path = Headers; sourceTree = ""; }; AEEE1FD411DC27B800029872 /* iOS */ = { isa = PBXGroup; children = ( AEEE1FDA11DC27B800029872 /* CedarApplicationDelegate.h */, 6628FCA014C503530016652A /* Cedar-iOS.h */, ); path = iOS; sourceTree = ""; }; AEEE1FDC11DC27B800029872 /* iOS */ = { isa = PBXGroup; children = ( 960118BB1434867E00825FFF /* NSBundle+MainBundleHijack.m */, AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */, ); path = iOS; sourceTree = ""; }; AEEE1FE711DC27B800029872 /* Spec */ = { isa = PBXGroup; children = ( 1F45A3E2180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m */, AEEE1FF211DC27B800029872 /* SpecSpec2.m */, AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */, AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */, AEEE1FF011DC27B800029872 /* CDRHooksSpec.mm */, 34F3DF811A6ABB21003041DA /* CDRNilSpec.mm */, 96EA1CB9142C6560001A78E0 /* CDRSpecFailureSpec.mm */, F7C9BBEC1D3E838800B694C0 /* CDRSpecRunSpec.mm */, 9672F0A81615C3F40012ED58 /* CDRSpecSpec.mm */, 96C95B7D161339160018606B /* CDRSymbolicatorSpec.mm */, 34681C2F18FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm */, AEEE1FEF11DC27B800029872 /* main.mm */, 96B5918E1630F5840068EA5E /* ObjCHeadersSpec.mm */, 96D34483144A845100352C4A /* SpecBundleApplicationTests.mm */, AEEE1FF111DC27B800029872 /* SpecSpec.mm */, 346D1A981BBB389A00BECD4B /* SpecBundle-Info.plist */, 66F00B5014C4D92500146D88 /* Doubles */, 96A07F0D13F27ED70021974D /* Focused */, AEEE1FEB11DC27B800029872 /* iOS */, AE8C879F1362068A006C9305 /* Matchers */, 1FE15C25186919F400207F0C /* Reporters */, AEEF360C19DF248F00794484 /* Resources */, 346D1AA01BBB445B00BECD4B /* SpecBundle */, E328612E1604F254001FA77E /* Support */, 34DB67471C2B4CBA00206663 /* Swift */, 346262791B99C1DB002CAEBD /* watchOS */, AE34723F19C2257A005CA6F1 /* XCTest */, ); path = Spec; sourceTree = ""; }; AEEE1FEB11DC27B800029872 /* iOS */ = { isa = PBXGroup; children = ( AE02E83018526E9F00414F19 /* Cedar-iOSSpec.mm */, AE7DD11117296CB20058EB3B /* CedarApplicationDelegateSpec.mm */, 228F3FA617E3ECD10000C8AF /* CDRSpyiOSSpec.mm */, AE5218D4175979D900A656BC /* WeakReferenceCompatibilitySpec.mm */, AEEE1FED11DC27B800029872 /* main.mm */, 346D1AA21BBB457900BECD4B /* Info.plist */, ); path = iOS; sourceTree = ""; }; AEEE202611DC286500029872 /* Frameworks */ = { isa = PBXGroup; children = ( 342FB2C61BC328320090E253 /* ApplicationServices.framework */, 346D1AAC1BBC46B600BECD4B /* QuartzCore.framework */, 346D1AA91BBC41FE00BECD4B /* Foundation.framework */, 96B5F9FB144A81A7000A6A5D /* CoreGraphics.framework */, 34D7C4B71BB9CB5700E8E523 /* libxml2.tbd */, 34FD46681B99D43400257186 /* libxml2.tbd */, 34A848571B9A4A0500396A09 /* UIKit.framework */, AEC40C57174ACAD900474D2D /* UIKit.framework */, ); name = Frameworks; sourceTree = ""; }; AEEF360C19DF248F00794484 /* Resources */ = { isa = PBXGroup; children = ( AEEF360F19DF27E400794484 /* edward.jpg */, AEEF360D19DF24AB00794484 /* image.png */, ); path = Resources; sourceTree = ""; }; AEF72FF913ECC16400786282 /* Container */ = { isa = PBXGroup; children = ( 34D1E67A18F7A2E6005161AD /* AnInstanceOf.h */, AEF7301013ECC25000786282 /* BeEmpty.h */, AE18A7FA13F4601400C8872C /* Contain.h */, AE8F9C141B795A7C00B956C5 /* ContainSubset.h */, ); path = Container; sourceTree = ""; }; AEF72FFA13ECC19200786282 /* Base */ = { isa = PBXGroup; children = ( AEF72FFB13ECC21E00786282 /* Base.h */, AEF72FFC13ECC21E00786282 /* BeCloseTo.h */, AE4A9457187F7D8F008566F5 /* BeFalsy.h */, AEF32FF1145A2D79002F93BB /* BeGreaterThan.h */, AEF3300B145B4F75002F93BB /* BeGTE.h */, AEF72FFD13ECC21E00786282 /* BeInstanceOf.h */, AEF33016145B6222002F93BB /* BeLessThan.h */, AEF33020145B69DE002F93BB /* BeLTE.h */, AEF72FFE13ECC21E00786282 /* BeNil.h */, AEF72FFF13ECC21E00786282 /* BeSameInstanceAs.h */, AEF7300013ECC21E00786282 /* BeTruthy.h */, 5898AEAF3FE8C683E6F23C1D /* ConformTo.h */, AEF7300113ECC21E00786282 /* Equal.h */, AE0721E2187518FD0031CC42 /* Exist.h */, AEB45A901496C8D800845D09 /* RaiseException.h */, CA17998C17F89C4B00C38060 /* RespondTo.h */, 346F64681B82D01700F64156 /* BlockMatcher.h */, ); path = Base; sourceTree = ""; }; AEF7301313ECC4AE00786282 /* Base */ = { isa = PBXGroup; children = ( AEF7301413ECC4AE00786282 /* BeCloseToSpec.mm */, AE4A945A187F7E52008566F5 /* BeFalsySpec.mm */, AE6F3F331458D7C100C98F1E /* BeGreaterThanSpec.mm */, AEF33008145B4E3B002F93BB /* BeGTESpec.mm */, AEF7301513ECC4AE00786282 /* BeInstanceOfSpec.mm */, AEF33012145B6188002F93BB /* BeLessThanSpec.mm */, AEF3301D145B68D7002F93BB /* BeLTESpec.mm */, 1F882AA9180F9B6300533238 /* BeNil_ARCSpec.mm */, AEF7301613ECC4AE00786282 /* BeNilSpec.mm */, 1F882AAB180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm */, AEF7301713ECC4AE00786282 /* BeSameInstanceAsSpec.mm */, AEF7301813ECC4AE00786282 /* BeTruthySpec.mm */, 5898A53A07BC580786243CD0 /* ConformToSpec.mm */, AEF7301913ECC4AE00786282 /* EqualSpec.mm */, AE0721DF187513870031CC42 /* ExistSpec.mm */, AEF7301A13ECC4AE00786282 /* MutableEqualSpec.mm */, AEBB92601496C1F000EEBD59 /* RaiseExceptionSpec.mm */, CA17999217F8A0EE00C38060 /* RespondToSpec.mm */, 346F646D1B82D3C900F64156 /* BlockMatcherSpec.mm */, AE0BF06E1B8E10D7000B0EE7 /* BlockMatcher_ARCSpecSpec.mm */, ); path = Base; sourceTree = ""; }; AEF7302913ECC4C100786282 /* Container */ = { isa = PBXGroup; children = ( AEF7302B13ECC4E700786282 /* BeEmptySpec.mm */, AE18A80913F4640600C8872C /* ContainSpec.mm */, F7C8F3031BC63A000088069D /* ContainSubsetSpec.mm */, ); path = Container; sourceTree = ""; }; AEF7302E13ECC6EE00786282 /* Stringifiers */ = { isa = PBXGroup; children = ( AEF7303813ECCB7B00786282 /* StringifiersBase.h */, AEF7303913ECCB7B00786282 /* StringifiersContainer.h */, ); path = Stringifiers; sourceTree = ""; }; E31179CE161FD90C007D3CDE /* ReporterHelpers */ = { isa = PBXGroup; children = ( 1F483E31187D39D000521F81 /* CDROTestNamer.m */, E31179D1161FD937007D3CDE /* CDRSlowTestStatistics.m */, ); path = ReporterHelpers; sourceTree = ""; }; E328612E1604F254001FA77E /* Support */ = { isa = PBXGroup; children = ( AE71E7CA175E958F002A54D5 /* ARCViewController.h */, AE71E7CB175E958F002A54D5 /* ARCViewController.m */, AE807887183C71950078C608 /* ArgumentReleaser.h */, AE807888183C71950078C608 /* ArgumentReleaser.m */, AE8F1D901850F6C00059E840 /* CedarObservedObject.h */, F71C2F321D3DAD71003B37DC /* CedarTestSpecBuilder.h */, F71C2F331D3DAD71003B37DC /* CedarTestSpecBuilder.m */, 343FAFE8190FDAEC0085AFEC /* DeallocNotifier.h */, 343FAFE9190FDAEC0085AFEC /* DeallocNotifier.m */, 4523F16026FC3298AB3B00BE /* ExampleWithPublicRunDates.h */, 4523F1D0182DEAB34B1E7C83 /* ExampleWithPublicRunDates.mm */, E32861301604F287001FA77E /* FibonacciCalculator.h */, E32861311604F287001FA77E /* FibonacciCalculator.m */, AED10EBA18F46C0E00950904 /* FooSuperclass.h */, AED10EBB18F46C0E00950904 /* FooSuperclass.m */, 4523FFB9BD607306C7ED94A3 /* GData */, AE3E8F35184FEEE000633740 /* ObjectWithCollections.h */, AE3E8F36184FEEE000633740 /* ObjectWithCollections.m */, AE06D87E17AEEE230084D27C /* ObjectWithForwardingTarget.h */, AE06D87F17AEEE230084D27C /* ObjectWithForwardingTarget.m */, E4BCFDD01817FA110083ED98 /* ObjectWithProperty.h */, E4BCFDD11817FA110083ED98 /* ObjectWithProperty.m */, 9D28051718E2321D00887CC4 /* ObjectWithValueEquality.h */, 9D28051818E2321D00887CC4 /* ObjectWithValueEquality.m */, AE5218D1175979CA00A656BC /* ObjectWithWeakDelegate.h */, AE5218D2175979CA00A656BC /* ObjectWithWeakDelegate.m */, AE807889183C71950078C608 /* SimpleIncrementer.h */, AE80788A183C71950078C608 /* SimpleIncrementer.m */, AE80788B183C71950078C608 /* SimpleKeyValueObserver.h */, AE80788C183C71950078C608 /* SimpleKeyValueObserver.m */, AEF52C26187F236D00C8D2D8 /* SimpleMultiplier.h */, 34AF814C1C53339300DB5249 /* TestReporter.h */, 34AF814D1C53339300DB5249 /* TestReporter.m */, ); path = Support; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 346261DC1B995239002CAEBD /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 346262031B99544D002CAEBD /* CDRClassFake.h in Headers */, 34D7C3C31BB9710800E8E523 /* CDRXCTestSupport.h in Headers */, 346262101B99546C002CAEBD /* BeLessThan.h in Headers */, 3462621A1B995473002CAEBD /* BeEmpty.h in Headers */, 3462620B1B99546C002CAEBD /* BeCloseTo.h in Headers */, 346262231B995491002CAEBD /* ComparatorsContainerConvenience.h in Headers */, 346262221B995491002CAEBD /* CompareGreaterThan.h in Headers */, 346262331B9954B8002CAEBD /* CDRExampleReporter.h in Headers */, 3462622C1B9954A8002CAEBD /* CedarMatchers.h in Headers */, 346261EF1B995422002CAEBD /* CDRNil.h in Headers */, 3462623D1B9954C1002CAEBD /* CDRHooks.h in Headers */, 346262401B9954C1002CAEBD /* CDRSpecFailure.h in Headers */, 346261F41B995422002CAEBD /* CDRTypeUtilities.h in Headers */, 346262091B99544D002CAEBD /* CDRFake.h in Headers */, 346262161B99546C002CAEBD /* Equal.h in Headers */, 346261FF1B995445002CAEBD /* AnyInstanceConformingToProtocolArgument.h in Headers */, 346262181B99546C002CAEBD /* RaiseException.h in Headers */, 346261EB1B995422002CAEBD /* CDROTestNamer.h in Headers */, 346262041B99544D002CAEBD /* HaveReceived.h in Headers */, 3462622E1B9954A8002CAEBD /* CedarStringifiers.h in Headers */, 346262001B99544D002CAEBD /* CDRProtocolFake.h in Headers */, 346262071B99544D002CAEBD /* StubbedMethod.h in Headers */, 346261EC1B995422002CAEBD /* CDRSlowTestStatistics.h in Headers */, 3462620A1B99546C002CAEBD /* Base.h in Headers */, 346261FB1B995445002CAEBD /* AnyInstanceArgument.h in Headers */, 346262201B995491002CAEBD /* ComparatorsContainer.h in Headers */, 346261F51B995426002CAEBD /* CDRXCTestCase.h in Headers */, 3462623E1B9954C1002CAEBD /* CDRSharedExampleGroupPool.h in Headers */, F7C9BC081D45E4E100B694C0 /* CDRRunState.h in Headers */, 346261F31B995422002CAEBD /* CDRSymbolicator.h in Headers */, 346261E71B995422002CAEBD /* CDRSpyInfo.h in Headers */, 346262081B99544D002CAEBD /* InvocationMatcher.h in Headers */, 3462620C1B99546C002CAEBD /* BeFalsy.h in Headers */, 346262191B99546C002CAEBD /* RespondTo.h in Headers */, F7C9BC0B1D45E4E500B694C0 /* CDRStateTracker.h in Headers */, 346261E81B995422002CAEBD /* CedarDoubleImpl.h in Headers */, 346262421B9954C1002CAEBD /* CDRVersion.h in Headers */, 34D1819C1BC7F0E60087EC0D /* BlockMatcher.h in Headers */, 346261FE1B995445002CAEBD /* AnyInstanceOfClassArgument.h in Headers */, 3462623A1B9954C1002CAEBD /* CDRExampleGroup.h in Headers */, 346261EA1B995422002CAEBD /* NSMethodSignature+Cedar.h in Headers */, 34D7C3C21BB9710300E8E523 /* CDRXCTestObserver.h in Headers */, 346261F81B995426002CAEBD /* NSInvocation+CDRXExample.h in Headers */, 346262141B99546C002CAEBD /* BeTruthy.h in Headers */, 346261E91B995422002CAEBD /* NSInvocation+Cedar.h in Headers */, 346262411B9954C1002CAEBD /* CDRSpecHelper.h in Headers */, 3462620D1B99546C002CAEBD /* BeGreaterThan.h in Headers */, 346262061B99544D002CAEBD /* RejectedMethod.h in Headers */, 34DB674C1C2B65EB00206663 /* ContainSubset.h in Headers */, 34C95F521C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */, 346261FD1B995445002CAEBD /* AnyArgument.h in Headers */, 346262211B995491002CAEBD /* CompareEqual.h in Headers */, 346262111B99546C002CAEBD /* BeLTE.h in Headers */, F7C9BC0F1D45E4EC00B694C0 /* CDRStateTracking.h in Headers */, 346262021B99544D002CAEBD /* CDRSpy.h in Headers */, 346261F11B995422002CAEBD /* CDRPrivateFunctions.h in Headers */, 3462622D1B9954A8002CAEBD /* CedarComparators.h in Headers */, 346261F21B995422002CAEBD /* CDRRuntimeUtilities.h in Headers */, 346262371B9954B8002CAEBD /* CDRBufferedDefaultReporter.h in Headers */, 346262121B99546C002CAEBD /* BeNil.h in Headers */, 346261FC1B995445002CAEBD /* ReturnValue.h in Headers */, 346262741B99BE9F002CAEBD /* UIGeometryCompareEqual.h in Headers */, 346261F91B995445002CAEBD /* Argument.h in Headers */, 346262301B9954A8002CAEBD /* ShouldSyntax.h in Headers */, 3462621E1B99548A002CAEBD /* StringifiersContainer.h in Headers */, 3462621C1B995473002CAEBD /* AnInstanceOf.h in Headers */, 3462623C1B9954C1002CAEBD /* CDRFunctions.h in Headers */, 346262751B99BE9F002CAEBD /* UIGeometryStringifiers.h in Headers */, 346262131B99546C002CAEBD /* BeSameInstanceAs.h in Headers */, 346261F71B995426002CAEBD /* CDRXCTestSuite.h in Headers */, 3462623B1B9954C1002CAEBD /* CDRExampleParent.h in Headers */, 346262381B9954C1002CAEBD /* CDRExample.h in Headers */, 346262321B9954B8002CAEBD /* CDRDefaultReporter.h in Headers */, 3462621B1B995473002CAEBD /* Contain.h in Headers */, 346262311B9954B8002CAEBD /* CDRColorizedReporter.h in Headers */, 346262151B99546C002CAEBD /* ConformTo.h in Headers */, 346262351B9954B8002CAEBD /* CDROTestReporter.h in Headers */, 34DB67521C2B8C1000206663 /* CedarReporters.h in Headers */, 3462620F1B99546C002CAEBD /* BeInstanceOf.h in Headers */, 346261FA1B995445002CAEBD /* ValueArgument.h in Headers */, 346262171B99546C002CAEBD /* Exist.h in Headers */, 346262241B995491002CAEBD /* CompareCloseTo.h in Headers */, 346262391B9954C1002CAEBD /* CDRExampleBase.h in Headers */, 346262011B99544D002CAEBD /* CedarDoubles.h in Headers */, 346262051B99544D002CAEBD /* CedarDouble.h in Headers */, 3462622B1B9954A8002CAEBD /* ActualValue.h in Headers */, 346262341B9954B8002CAEBD /* CDRJUnitXMLReporter.h in Headers */, 3462621F1B995491002CAEBD /* ComparatorsBase.h in Headers */, 3462621D1B99548A002CAEBD /* StringifiersBase.h in Headers */, 3462623F1B9954C1002CAEBD /* CDRSpec.h in Headers */, 346261ED1B995422002CAEBD /* CDRReportDispatcher.h in Headers */, 346262361B9954B8002CAEBD /* CDRTeamCityReporter.h in Headers */, 34D7C3C41BB9710F00E8E523 /* CDRSpecRun.h in Headers */, 346262431B9954C1002CAEBD /* Cedar.h in Headers */, 346261EE1B995422002CAEBD /* CDRBlockHelper.h in Headers */, 3462620E1B99546C002CAEBD /* BeGTE.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 34D7C3C71BB9747400E8E523 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 34D7C4631BB9B5F100E8E523 /* Cedar.h in Headers */, 34D7C4321BB9B5B200E8E523 /* BeGTE.h in Headers */, 34D7C4611BB9B5F100E8E523 /* CDRSpecHelper.h in Headers */, 34D7C4401BB9B5B900E8E523 /* AnInstanceOf.h in Headers */, F7C9BC071D45E4E000B694C0 /* CDRRunState.h in Headers */, 34D7C4601BB9B5F100E8E523 /* CDRSpecFailure.h in Headers */, 34D7C43D1BB9B5B200E8E523 /* RespondTo.h in Headers */, 34D7C42E1BB9B5B200E8E523 /* Base.h in Headers */, 34D7C4231BB9B59200E8E523 /* CDRClassFake.h in Headers */, 34D7C4061BB9B53C00E8E523 /* CDRSpyInfo.h in Headers */, 34D7C4571BB9B5E900E8E523 /* CDRBufferedDefaultReporter.h in Headers */, 34D7C40E1BB9B54F00E8E523 /* CDRXCTestObserver.h in Headers */, 34D7C4331BB9B5B200E8E523 /* BeInstanceOf.h in Headers */, 34D7C4521BB9B5E900E8E523 /* CDRDefaultReporter.h in Headers */, 34D7C43C1BB9B5B200E8E523 /* RaiseException.h in Headers */, 34D7C4531BB9B5E900E8E523 /* CDRExampleReporter.h in Headers */, 34D7C4511BB9B5E900E8E523 /* CDRColorizedReporter.h in Headers */, 34D7C4421BB9B5BF00E8E523 /* StringifiersContainer.h in Headers */, 34D7C45C1BB9B5F100E8E523 /* CDRFunctions.h in Headers */, 34D7C4591BB9B5F100E8E523 /* CDRExampleBase.h in Headers */, 34D7C43B1BB9B5B200E8E523 /* Exist.h in Headers */, 34D7C4291BB9B59200E8E523 /* CDRFake.h in Headers */, 34C95F531C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */, 34DB674D1C2B65EC00206663 /* ContainSubset.h in Headers */, 34D7C45E1BB9B5F100E8E523 /* CDRSharedExampleGroupPool.h in Headers */, 34D7C45F1BB9B5F100E8E523 /* CDRSpec.h in Headers */, 34D7C41F1BB9B56D00E8E523 /* AnyInstanceConformingToProtocolArgument.h in Headers */, 34DB67531C2B8C1000206663 /* CedarReporters.h in Headers */, 34D7C43F1BB9B5B900E8E523 /* Contain.h in Headers */, 34D7C4101BB9B54F00E8E523 /* CDRXCTestSupport.h in Headers */, 34D7C4241BB9B59200E8E523 /* HaveReceived.h in Headers */, 34D7C4201BB9B59200E8E523 /* CDRProtocolFake.h in Headers */, 34D7C4341BB9B5B200E8E523 /* BeLessThan.h in Headers */, 34D7C4271BB9B59200E8E523 /* StubbedMethod.h in Headers */, 34D7C40C1BB9B54A00E8E523 /* CDRReportDispatcher.h in Headers */, F7C9BC0E1D45E4EC00B694C0 /* CDRStateTracking.h in Headers */, 34D7C4151BB9B55500E8E523 /* CDRRuntimeUtilities.h in Headers */, 34D7C43A1BB9B5B200E8E523 /* Equal.h in Headers */, 34D7C44C1BB9B5DF00E8E523 /* ActualValue.h in Headers */, 34D7C41B1BB9B56D00E8E523 /* AnyInstanceArgument.h in Headers */, 34D7C4381BB9B5B200E8E523 /* BeTruthy.h in Headers */, 34D7C4091BB9B53F00E8E523 /* NSMethodSignature+Cedar.h in Headers */, 34D7C4301BB9B5B200E8E523 /* BeFalsy.h in Headers */, 34D7C40A1BB9B54600E8E523 /* CDROTestNamer.h in Headers */, 34D7C4621BB9B5F100E8E523 /* CDRVersion.h in Headers */, 34D7C4481BB9B5C500E8E523 /* CompareCloseTo.h in Headers */, 34D7C4581BB9B5F100E8E523 /* CDRExample.h in Headers */, 34D7C4441BB9B5C500E8E523 /* ComparatorsContainer.h in Headers */, 34D7C4411BB9B5BF00E8E523 /* StringifiersBase.h in Headers */, 34D7C4181BB9B55500E8E523 /* CDRTypeUtilities.h in Headers */, 34D7C4081BB9B53F00E8E523 /* NSInvocation+Cedar.h in Headers */, 34D7C4461BB9B5C500E8E523 /* CompareGreaterThan.h in Headers */, 34D7C44B1BB9B5D300E8E523 /* UIGeometryStringifiers.h in Headers */, 34D7C4281BB9B59200E8E523 /* InvocationMatcher.h in Headers */, 34D7C40D1BB9B54F00E8E523 /* CDRXCTestCase.h in Headers */, 34D7C4541BB9B5E900E8E523 /* CDRJUnitXMLReporter.h in Headers */, 34D7C41E1BB9B56D00E8E523 /* AnyInstanceOfClassArgument.h in Headers */, 34D7C4141BB9B55500E8E523 /* CDRPrivateFunctions.h in Headers */, 34D7C4121BB9B55500E8E523 /* CDRBlockHelper.h in Headers */, 34D7C40B1BB9B54600E8E523 /* CDRSlowTestStatistics.h in Headers */, 34D7C4261BB9B59200E8E523 /* RejectedMethod.h in Headers */, 34D7C4431BB9B5C500E8E523 /* ComparatorsBase.h in Headers */, 34D7C41D1BB9B56D00E8E523 /* AnyArgument.h in Headers */, 34D7C4351BB9B5B200E8E523 /* BeLTE.h in Headers */, 34D7C4451BB9B5C500E8E523 /* CompareEqual.h in Headers */, 34D7C4501BB9B5E400E8E523 /* ShouldSyntax.h in Headers */, 34D7C4371BB9B5B200E8E523 /* BeSameInstanceAs.h in Headers */, 34D7C42F1BB9B5B200E8E523 /* BeCloseTo.h in Headers */, 34D7C4221BB9B59200E8E523 /* CDRSpy.h in Headers */, 34D7C4161BB9B55500E8E523 /* CDRSpecRun.h in Headers */, 34D7C42D1BB9B5A400E8E523 /* Cedar-iOS.h in Headers */, 34D7C44D1BB9B5DF00E8E523 /* CedarMatchers.h in Headers */, 34D7C44A1BB9B5D300E8E523 /* UIGeometryCompareEqual.h in Headers */, 34D7C4391BB9B5B200E8E523 /* ConformTo.h in Headers */, 34D7C4361BB9B5B200E8E523 /* BeNil.h in Headers */, 34D7C40F1BB9B54F00E8E523 /* CDRXCTestSuite.h in Headers */, 34D7C4311BB9B5B200E8E523 /* BeGreaterThan.h in Headers */, 34D7C44F1BB9B5DF00E8E523 /* CedarStringifiers.h in Headers */, 34D7C4491BB9B5D300E8E523 /* UIKitComparatorsContainer.h in Headers */, 34D7C45B1BB9B5F100E8E523 /* CDRExampleParent.h in Headers */, 34D7C41C1BB9B56D00E8E523 /* ReturnValue.h in Headers */, 34D7C44E1BB9B5DF00E8E523 /* CedarComparators.h in Headers */, 34D1819D1BC7F0E70087EC0D /* BlockMatcher.h in Headers */, 34D7C42C1BB9B5A400E8E523 /* CedarApplicationDelegate.h in Headers */, 34D7C4471BB9B5C500E8E523 /* ComparatorsContainerConvenience.h in Headers */, 34D7C4561BB9B5E900E8E523 /* CDRTeamCityReporter.h in Headers */, 34D7C4191BB9B56D00E8E523 /* Argument.h in Headers */, 34D7C4071BB9B53C00E8E523 /* CedarDoubleImpl.h in Headers */, 34D7C4131BB9B55500E8E523 /* CDRNil.h in Headers */, 34D7C4551BB9B5E900E8E523 /* CDROTestReporter.h in Headers */, 34D7C45A1BB9B5F100E8E523 /* CDRExampleGroup.h in Headers */, 34D7C41A1BB9B56D00E8E523 /* ValueArgument.h in Headers */, 34D7C4211BB9B59200E8E523 /* CedarDoubles.h in Headers */, 34D7C4251BB9B59200E8E523 /* CedarDouble.h in Headers */, 34D7C4171BB9B55500E8E523 /* CDRSymbolicator.h in Headers */, 34D7C4111BB9B54F00E8E523 /* NSInvocation+CDRXExample.h in Headers */, 34D7C43E1BB9B5B900E8E523 /* BeEmpty.h in Headers */, 34D7C45D1BB9B5F100E8E523 /* CDRHooks.h in Headers */, F7C9BC0A1D45E4E400B694C0 /* CDRStateTracker.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; AE4864F51B067620005DB302 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( AE4865E11B0690B1005DB302 /* Cedar.h in Headers */, AE4865A51B0690AF005DB302 /* Argument.h in Headers */, AE4865A61B0690AF005DB302 /* ValueArgument.h in Headers */, AE4865A71B0690AF005DB302 /* AnyInstanceArgument.h in Headers */, F7C9BC091D45E4E100B694C0 /* CDRRunState.h in Headers */, AE4865A81B0690AF005DB302 /* ReturnValue.h in Headers */, AE4865A91B0690AF005DB302 /* AnyArgument.h in Headers */, AE4865AA1B0690AF005DB302 /* AnyInstanceOfClassArgument.h in Headers */, AE4865AB1B0690AF005DB302 /* AnyInstanceConformingToProtocolArgument.h in Headers */, AE4865AC1B0690AF005DB302 /* CDRProtocolFake.h in Headers */, AE4865AD1B0690AF005DB302 /* CedarDoubles.h in Headers */, AE4865AE1B0690AF005DB302 /* CDRSpy.h in Headers */, AE4865AF1B0690AF005DB302 /* CDRClassFake.h in Headers */, AE4865B01B0690AF005DB302 /* HaveReceived.h in Headers */, AE4865B11B0690AF005DB302 /* CedarDouble.h in Headers */, AE4865B51B0690B0005DB302 /* CDRFake.h in Headers */, AE4865B61B0690B0005DB302 /* CedarApplicationDelegate.h in Headers */, AE4865B71B0690B0005DB302 /* Cedar-iOS.h in Headers */, AE4865B81B0690B0005DB302 /* Base.h in Headers */, 3492DAA11BA6F9E70032B35A /* CDRSpecRun.h in Headers */, AE4865B91B0690B0005DB302 /* BeCloseTo.h in Headers */, AE4865BA1B0690B0005DB302 /* BeFalsy.h in Headers */, 34C95F511C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */, 34DB674B1C2B65EA00206663 /* ContainSubset.h in Headers */, AE4865BB1B0690B0005DB302 /* BeGreaterThan.h in Headers */, AE4865BC1B0690B0005DB302 /* BeGTE.h in Headers */, AE4865BD1B0690B0005DB302 /* BeInstanceOf.h in Headers */, 34DB67511C2B8C1000206663 /* CedarReporters.h in Headers */, AE4865BE1B0690B0005DB302 /* BeLessThan.h in Headers */, AE4865BF1B0690B0005DB302 /* BeLTE.h in Headers */, AE4865C01B0690B0005DB302 /* BeNil.h in Headers */, AE4865C11B0690B0005DB302 /* BeSameInstanceAs.h in Headers */, AE4865C21B0690B0005DB302 /* BeTruthy.h in Headers */, AE4865C31B0690B0005DB302 /* ConformTo.h in Headers */, AE4865C41B0690B0005DB302 /* Equal.h in Headers */, F7C9BC101D45E4ED00B694C0 /* CDRStateTracking.h in Headers */, AE4865C51B0690B0005DB302 /* Exist.h in Headers */, AE4865C61B0690B0005DB302 /* RaiseException.h in Headers */, AE4865C71B0690B0005DB302 /* RespondTo.h in Headers */, AE4865C81B0690B0005DB302 /* StringifiersBase.h in Headers */, AE4865C91B0690B0005DB302 /* StringifiersContainer.h in Headers */, 346F64751B82D90C00F64156 /* BlockMatcher.h in Headers */, AE4865CA1B0690B0005DB302 /* ComparatorsBase.h in Headers */, AE4865CB1B0690B0005DB302 /* ComparatorsContainer.h in Headers */, AE4865CC1B0690B0005DB302 /* CompareEqual.h in Headers */, AE4865CD1B0690B0005DB302 /* CompareGreaterThan.h in Headers */, AE4865CE1B0690B0005DB302 /* ComparatorsContainerConvenience.h in Headers */, AE4865CF1B0690B0005DB302 /* CompareCloseTo.h in Headers */, AE4865D11B0690B1005DB302 /* CedarMatchers.h in Headers */, AE4865D21B0690B1005DB302 /* CedarComparators.h in Headers */, AE4865D31B0690B1005DB302 /* CedarStringifiers.h in Headers */, AE4865D51B0690B1005DB302 /* ShouldSyntax.h in Headers */, AE4865D61B0690B1005DB302 /* CDRVersion.h in Headers */, AE4865D71B0690B1005DB302 /* CDRExample.h in Headers */, AE4865D81B0690B1005DB302 /* CDRExampleBase.h in Headers */, AE4865D91B0690B1005DB302 /* CDRExampleGroup.h in Headers */, AE4865DA1B0690B1005DB302 /* CDRExampleParent.h in Headers */, AE4865DB1B0690B1005DB302 /* CDRFunctions.h in Headers */, 34322B0A1BA740B900D0CFBD /* CDRXCTestObserver.h in Headers */, AE4865DC1B0690B1005DB302 /* CDRHooks.h in Headers */, AE4865DD1B0690B1005DB302 /* CDRSharedExampleGroupPool.h in Headers */, AE4865DE1B0690B1005DB302 /* CDRSpec.h in Headers */, AE4865DF1B0690B1005DB302 /* CDRSpecFailure.h in Headers */, AE4865E21B0690B2005DB302 /* CDRSpecHelper.h in Headers */, AE4865ED1B069353005DB302 /* BeEmpty.h in Headers */, AE4865EE1B069353005DB302 /* Contain.h in Headers */, AE4865EF1B069353005DB302 /* AnInstanceOf.h in Headers */, AE4865F01B069353005DB302 /* UIGeometryCompareEqual.h in Headers */, AE4865F11B069353005DB302 /* UIGeometryStringifiers.h in Headers */, AE4865F21B069353005DB302 /* UIKitComparatorsContainer.h in Headers */, AE4865D01B0690B0005DB302 /* ActualValue.h in Headers */, AE4865B41B0690AF005DB302 /* InvocationMatcher.h in Headers */, AE4865E31B0690B2005DB302 /* CDRBlockHelper.h in Headers */, AE4865E51B0690B2005DB302 /* CDRNil.h in Headers */, AE4865551B06769D005DB302 /* CDRBufferedDefaultReporter.h in Headers */, AE4865681B06769F005DB302 /* CDRXCTestSuite.h in Headers */, AE4865E41B0690B2005DB302 /* CDRTypeUtilities.h in Headers */, AE4865A41B0690AF005DB302 /* NSInvocation+Cedar.h in Headers */, AE4865121B06769B005DB302 /* NSMethodSignature+Cedar.h in Headers */, 3492DA9C1BA672AD0032B35A /* CDRXCTestSupport.h in Headers */, AE4865E71B0691C9005DB302 /* CDRColorizedReporter.h in Headers */, AE48656A1B06769F005DB302 /* NSInvocation+CDRXExample.h in Headers */, AE4865231B06769B005DB302 /* CedarDoubleImpl.h in Headers */, AE48651D1B06769B005DB302 /* CDRSpyInfo.h in Headers */, AE4865E81B0691EA005DB302 /* CDRTeamCityReporter.h in Headers */, AE4865691B06769F005DB302 /* CDRXCTestCase.h in Headers */, 34322B0B1BA742B400D0CFBD /* CDRPrivateFunctions.h in Headers */, AE4865EC1B069253005DB302 /* CDROTestReporter.h in Headers */, AE4865EA1B069253005DB302 /* CDRExampleReporter.h in Headers */, AE4865531B06769D005DB302 /* CDRReportDispatcher.h in Headers */, AE4865EB1B069253005DB302 /* CDRJUnitXMLReporter.h in Headers */, AE4865E01B0690B1005DB302 /* CDRSymbolicator.h in Headers */, AE4865E61B0690B2005DB302 /* CDRSlowTestStatistics.h in Headers */, AE48656B1B06769F005DB302 /* CDROTestNamer.h in Headers */, AE4865E91B069253005DB302 /* CDRDefaultReporter.h in Headers */, AE4865661B06769F005DB302 /* CDRRuntimeUtilities.h in Headers */, AE4865B21B0690AF005DB302 /* RejectedMethod.h in Headers */, AE4865B31B0690AF005DB302 /* StubbedMethod.h in Headers */, F7C9BC0C1D45E4E500B694C0 /* CDRStateTracker.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE1FB111DC271300029872 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( AEEE1FFB11DC27B800029872 /* CDRExampleBase.h in Headers */, AEEE1FFD11DC27B800029872 /* CDRExampleParent.h in Headers */, AEEE1FFE11DC27B800029872 /* CDRExampleReporter.h in Headers */, 3492DA9F1BA6F9E70032B35A /* CDRSpecRun.h in Headers */, AEEE1FFF11DC27B800029872 /* CDRFunctions.h in Headers */, AEEE200011DC27B800029872 /* CDRSpec.h in Headers */, AEEE200111DC27B800029872 /* Cedar.h in Headers */, AEEE200811DC27B800029872 /* CDRSpecHelper.h in Headers */, AE91CA6C11DE64A3002BA6B9 /* CDRSharedExampleGroupPool.h in Headers */, 1FE15C1B1869091900207F0C /* CDRReportDispatcher.h in Headers */, 3492DA9B1BA672AB0032B35A /* CDRXCTestSupport.h in Headers */, AE8C880F13626FA5006C9305 /* CDRSpecFailure.h in Headers */, AE0AF56513E9C0E300029396 /* CedarMatchers.h in Headers */, AE0AF58513E9E87E00029396 /* ActualValue.h in Headers */, AEF72F7813EC730700786282 /* CedarComparators.h in Headers */, AEF72F7B13EC734000786282 /* CedarStringifiers.h in Headers */, AE4E9B9219C8B44700D794CE /* NSInvocation+CDRXExample.h in Headers */, 34640DA91B6965060083EB01 /* CDRNil.h in Headers */, AEF7301113ECC25000786282 /* BeEmpty.h in Headers */, AEF7303A13ECCB7B00786282 /* StringifiersBase.h in Headers */, AEF7303B13ECCB7B00786282 /* StringifiersContainer.h in Headers */, AE18A7CA13F453CC00C8872C /* Base.h in Headers */, AE18A7CB13F453CC00C8872C /* BeCloseTo.h in Headers */, AE18A7CC13F453CC00C8872C /* BeInstanceOf.h in Headers */, AE18A7CD13F453CC00C8872C /* BeNil.h in Headers */, AE4A9458187F7D8F008566F5 /* BeFalsy.h in Headers */, AE18A7CE13F453CC00C8872C /* BeSameInstanceAs.h in Headers */, AEF8FB0719E6000E00DD4FE4 /* CDRVersion.h in Headers */, F7C9BC011D45E16200B694C0 /* CDRRunState.h in Headers */, 34640DA81B6964FE0083EB01 /* CDRTypeUtilities.h in Headers */, B86B685F1A1326E200F283F7 /* OSXGeometryStringifiers.h in Headers */, 2234907D18009DA6001C8E8D /* CDRHooks.h in Headers */, AE18A7CF13F453CC00C8872C /* BeTruthy.h in Headers */, AE18A7D013F453CC00C8872C /* Equal.h in Headers */, F7C9BC0D1D45E4E600B694C0 /* CDRStateTracker.h in Headers */, AE18A7D313F45BE500C8872C /* ComparatorsBase.h in Headers */, AE0F354719E7059D00B9F116 /* OSXGeometryCompareEqual.h in Headers */, AE18A7D613F45BFC00C8872C /* ComparatorsContainer.h in Headers */, AE9AA67515AB601500617E1A /* CedarDoubles.h in Headers */, AE9AA67615AB601500617E1A /* CDRSpy.h in Headers */, 34322B091BA740B900D0CFBD /* CDRXCTestObserver.h in Headers */, AE18A7FB13F4601400C8872C /* Contain.h in Headers */, AE9AA68915AC729800617E1A /* CedarDouble.h in Headers */, AE0F354E19E87D6F00B9F116 /* CompareCloseTo.h in Headers */, AE0721E3187518FD0031CC42 /* Exist.h in Headers */, AE34724B19C37ECF005CA6F1 /* CDRXCTestCase.h in Headers */, AE74907415B493B5008EA127 /* CDRFake.h in Headers */, 34DB674A1C2B65EA00206663 /* ContainSubset.h in Headers */, 34C95F501C2DD7B30055F089 /* CDRNullabilityCompat.h in Headers */, 34640DA71B6964F90083EB01 /* CDRBlockHelper.h in Headers */, AE9AA67B15AB72DA00617E1A /* CDRClassFake.h in Headers */, AE74902F15B45E80008EA127 /* CDRProtocolFake.h in Headers */, AE9AA67815AB601500617E1A /* HaveReceived.h in Headers */, F7C9BC111D45E4ED00B694C0 /* CDRStateTracking.h in Headers */, AEF32FF2145A2D79002F93BB /* BeGreaterThan.h in Headers */, AE597B4115B0638B00EEF305 /* InvocationMatcher.h in Headers */, AEF32FF4145A2E91002F93BB /* CompareEqual.h in Headers */, AEAA191419DCC5A900194E95 /* NSMethodSignature+Cedar.h in Headers */, AEF32FF8145A2EDF002F93BB /* CompareGreaterThan.h in Headers */, AEF3300C145B4F75002F93BB /* BeGTE.h in Headers */, AEF33017145B6222002F93BB /* BeLessThan.h in Headers */, 1FF449B518A0C24400AF94B0 /* CDRBufferedDefaultReporter.h in Headers */, E31179D2161FD937007D3CDE /* CDRSlowTestStatistics.h in Headers */, AEF33021145B69DE002F93BB /* BeLTE.h in Headers */, AE4A945E1880792E008566F5 /* RejectedMethod.h in Headers */, AEEE1FFA11DC27B800029872 /* CDRExample.h in Headers */, AEEE1FFC11DC27B800029872 /* CDRExampleGroup.h in Headers */, 969B6F96160F1FEC00C7C792 /* CDRSymbolicator.h in Headers */, AE84F0DB145B70DD00769F85 /* ShouldSyntax.h in Headers */, 34147770191408C900CBA385 /* AnInstanceOf.h in Headers */, AE31A29F19C0F23F00C438C1 /* CDRXCTestSuite.h in Headers */, 34777EB71B99451200A69FCF /* CDRPrivateFunctions.h in Headers */, AEB45A911496C8D800845D09 /* RaiseException.h in Headers */, AEC9DEED12C2CC7E0039512D /* CDRColorizedReporter.h in Headers */, 96EA1CAE142C6449001A78E0 /* CDROTestReporter.h in Headers */, 42064466139B44EC00C85605 /* CDRTeamCityReporter.h in Headers */, 34DB67501C2B8C1000206663 /* CedarReporters.h in Headers */, AEEE1FF911DC27B800029872 /* CDRDefaultReporter.h in Headers */, 1F483E32187D39D000521F81 /* CDROTestNamer.h in Headers */, 492951DD1481AAD800FA8916 /* CDRJUnitXMLReporter.h in Headers */, 5898A1BAE1D014B764946811 /* ConformTo.h in Headers */, 34ADD2EB19220F7400B057AC /* AnyInstanceOfClassArgument.h in Headers */, 34ADD2EC19220F7400B057AC /* AnyInstanceConformingToProtocolArgument.h in Headers */, 3414776E191406E700CBA385 /* ComparatorsContainerConvenience.h in Headers */, AE9AA6D415AE087D00617E1A /* StubbedMethod.h in Headers */, AEAA191219DCC5A900194E95 /* NSInvocation+Cedar.h in Headers */, AE9AA6DB15AE0B0400617E1A /* CedarDoubleImpl.h in Headers */, AECF136115D1425C003AAB9C /* Argument.h in Headers */, AECF136415D14274003AAB9C /* ValueArgument.h in Headers */, AECF136715D142E3003AAB9C /* ReturnValue.h in Headers */, AECF136A15D1439B003AAB9C /* AnyArgument.h in Headers */, 346F646A1B82D01700F64156 /* BlockMatcher.h in Headers */, AE55BF1E19A7CFAB005948E6 /* CDRRuntimeUtilities.h in Headers */, AE94D03F15F341B200A0C2B7 /* AnyInstanceArgument.h in Headers */, AEE8DBD4175FFCF3008AF18A /* CDRSpyInfo.h in Headers */, CA17998D17F89C4B00C38060 /* RespondTo.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 1F45A3C8180E4796003C1E36 /* Cedar-iOS SpecBundle */ = { isa = PBXNativeTarget; buildConfigurationList = 1F45A3DA180E4796003C1E36 /* Build configuration list for PBXNativeTarget "Cedar-iOS SpecBundle" */; buildPhases = ( 1F45A3CD180E4796003C1E36 /* Sources */, 1F45A3D2180E4796003C1E36 /* Frameworks */, ); buildRules = ( ); dependencies = ( 346D1AA71BBC406000BECD4B /* PBXTargetDependency */, 1F45A3CB180E4796003C1E36 /* PBXTargetDependency */, ); name = "Cedar-iOS SpecBundle"; productName = OCUnitAppTests; productReference = 1F45A3DD180E4796003C1E36 /* Cedar-iOS SpecBundle.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 346261DE1B995239002CAEBD /* Cedar-watchOS */ = { isa = PBXNativeTarget; buildConfigurationList = 346261E61B99523A002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS" */; buildPhases = ( 346261DA1B995239002CAEBD /* Sources */, 346261DC1B995239002CAEBD /* Headers */, 34D7C3BF1BB9703400E8E523 /* Set Git SHA on Framework */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-watchOS"; productName = "Cedar-watchOS"; productReference = 346261DF1B995239002CAEBD /* Cedar.framework */; productType = "com.apple.product-type.framework"; }; 346262771B99C1DB002CAEBD /* Cedar-watchOS Specs */ = { isa = PBXNativeTarget; buildConfigurationList = 346262991B99C1DC002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS Specs" */; buildPhases = ( 346262761B99C1DB002CAEBD /* Resources */, 346262981B99C1DC002CAEBD /* Embed App Extensions */, ); buildRules = ( ); dependencies = ( 346262871B99C1DC002CAEBD /* PBXTargetDependency */, ); name = "Cedar-watchOS Specs"; productName = "Cedar-watchOS Specs"; productReference = 346262781B99C1DB002CAEBD /* Cedar-watchOS Specs.app */; productType = "com.apple.product-type.application.watchapp2"; }; 346262831B99C1DC002CAEBD /* Cedar-watchOS Specs Extension */ = { isa = PBXNativeTarget; buildConfigurationList = 346262951B99C1DC002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS Specs Extension" */; buildPhases = ( 346262801B99C1DC002CAEBD /* Sources */, 346262811B99C1DC002CAEBD /* Frameworks */, 346262821B99C1DC002CAEBD /* Resources */, 3462629F1B99D0CA002CAEBD /* CopyFiles */, ); buildRules = ( ); dependencies = ( 3462629E1B99D0BB002CAEBD /* PBXTargetDependency */, ); name = "Cedar-watchOS Specs Extension"; productName = "Cedar-watchOS Specs Extension"; productReference = 346262841B99C1DC002CAEBD /* Cedar-watchOS Specs Extension.appex */; productType = "com.apple.product-type.watchkit2-extension"; }; 34852D131BBE35FF0072D249 /* Cedar-watchOS HostApp */ = { isa = PBXNativeTarget; buildConfigurationList = 34852D1E1BBE35FF0072D249 /* Build configuration list for PBXNativeTarget "Cedar-watchOS HostApp" */; buildPhases = ( 34852D141BBE35FF0072D249 /* Sources */, 34852D171BBE35FF0072D249 /* Frameworks */, 34852D1C1BBE35FF0072D249 /* Embed Watch Content */, ); buildRules = ( ); dependencies = ( 34852D241BBE36B90072D249 /* PBXTargetDependency */, ); name = "Cedar-watchOS HostApp"; productName = OCUnitApp; productReference = 34852D211BBE35FF0072D249 /* Cedar-watchOS HostApp.app */; productType = "com.apple.product-type.application"; }; 34D7C3C91BB9747400E8E523 /* Cedar-tvOS */ = { isa = PBXNativeTarget; buildConfigurationList = 34D7C3D11BB9747400E8E523 /* Build configuration list for PBXNativeTarget "Cedar-tvOS" */; buildPhases = ( 34D7C3C51BB9747400E8E523 /* Sources */, 34D7C3C71BB9747400E8E523 /* Headers */, 34D7C4641BB9B66600E8E523 /* Set Git SHA on Framework */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-tvOS"; productName = "Cedar-tvOS"; productReference = 34D7C3CA1BB9747400E8E523 /* Cedar.framework */; productType = "com.apple.product-type.framework"; }; 34D7C4681BB9B71600E8E523 /* Cedar-tvOS SpecBundle */ = { isa = PBXNativeTarget; buildConfigurationList = 34D7C46E1BB9B71600E8E523 /* Build configuration list for PBXNativeTarget "Cedar-tvOS SpecBundle" */; buildPhases = ( 34D7C4651BB9B71600E8E523 /* Sources */, 34D7C4661BB9B71600E8E523 /* Frameworks */, 34D7C4671BB9B71600E8E523 /* Resources */, ); buildRules = ( ); dependencies = ( 34D7C4721BB9B72300E8E523 /* PBXTargetDependency */, ); name = "Cedar-tvOS SpecBundle"; productName = "Cedar-tvOS-SpecBundle"; productReference = 34D7C4691BB9B71600E8E523 /* Cedar-tvOS SpecBundle.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 96A07EEE13F276640021974D /* Cedar-OSX FocusedSpecs */ = { isa = PBXNativeTarget; buildConfigurationList = 96A07F0513F276640021974D /* Build configuration list for PBXNativeTarget "Cedar-OSX FocusedSpecs" */; buildPhases = ( 96A07EF313F276640021974D /* Sources */, 96A07F0213F276640021974D /* Frameworks */, ); buildRules = ( ); dependencies = ( 96A07EEF13F276640021974D /* PBXTargetDependency */, ); name = "Cedar-OSX FocusedSpecs"; productName = Specs; productReference = 96A07F0813F276640021974D /* Cedar-OSX FocusedSpecs */; productType = "com.apple.product-type.tool"; }; 96B5F9F5144A81A7000A6A5D /* Cedar-iOS HostApp */ = { isa = PBXNativeTarget; buildConfigurationList = 96B5FA22144A81A8000A6A5D /* Build configuration list for PBXNativeTarget "Cedar-iOS HostApp" */; buildPhases = ( 96B5F9F2144A81A7000A6A5D /* Sources */, 96B5F9F3144A81A7000A6A5D /* Frameworks */, 96B5F9F4144A81A7000A6A5D /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-iOS HostApp"; productName = OCUnitApp; productReference = 96B5F9F6144A81A7000A6A5D /* Cedar-iOS HostApp.app */; productType = "com.apple.product-type.application"; }; AE02E7E3184EABCD00414F19 /* Cedar-iOS StaticFrameworkSpecs */ = { isa = PBXNativeTarget; buildConfigurationList = AE02E808184EABCE00414F19 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticFrameworkSpecs" */; buildPhases = ( AE02E7E0184EABCD00414F19 /* Sources */, AE02E7E1184EABCD00414F19 /* Frameworks */, ); buildRules = ( ); dependencies = ( AE02E80F184EADE100414F19 /* PBXTargetDependency */, ); name = "Cedar-iOS StaticFrameworkSpecs"; productName = "Cedar-iOS.FrameworkSpecs"; productReference = AE02E7E4184EABCD00414F19 /* Cedar-iOS StaticFrameworkSpecs.app */; productType = "com.apple.product-type.application"; }; AE03FBE81B06C33B00013784 /* Cedar-iOS Specs */ = { isa = PBXNativeTarget; buildConfigurationList = AE03FC0D1B06C33B00013784 /* Build configuration list for PBXNativeTarget "Cedar-iOS Specs" */; buildPhases = ( AE03FBE51B06C33B00013784 /* Sources */, AE03FBE61B06C33B00013784 /* Frameworks */, AE03FBE71B06C33B00013784 /* Resources */, AE03FC121B06C39D00013784 /* Embed Frameworks */, ); buildRules = ( ); dependencies = ( AE03FC111B06C39500013784 /* PBXTargetDependency */, ); name = "Cedar-iOS Specs"; productName = "Cedar-iOS-Framework Spec"; productReference = AE03FBE91B06C33B00013784 /* Cedar-iOS Specs.app */; productType = "com.apple.product-type.application"; }; AE248F9719DCD52500092C14 /* Cedar-OSX HostApp */ = { isa = PBXNativeTarget; buildConfigurationList = AE248FB219DCD52500092C14 /* Build configuration list for PBXNativeTarget "Cedar-OSX HostApp" */; buildPhases = ( AE248F9419DCD52500092C14 /* Sources */, AE248F9519DCD52500092C14 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-OSX HostApp"; productName = "OS X Host App"; productReference = AE248F9819DCD52500092C14 /* Cedar-OSX HostApp.app */; productType = "com.apple.product-type.application"; }; AE248FA919DCD52500092C14 /* Cedar-OSX SpecBundle */ = { isa = PBXNativeTarget; buildConfigurationList = AE248FB519DCD52500092C14 /* Build configuration list for PBXNativeTarget "Cedar-OSX SpecBundle" */; buildPhases = ( AE248FA619DCD52500092C14 /* Sources */, AE248FA719DCD52500092C14 /* Frameworks */, ); buildRules = ( ); dependencies = ( AE248FC019DCD5E200092C14 /* PBXTargetDependency */, AE248FAC19DCD52500092C14 /* PBXTargetDependency */, ); name = "Cedar-OSX SpecBundle"; productName = "OS X Host AppTests"; productReference = AE248FAA19DCD52500092C14 /* Cedar-OSX SpecBundle.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; AE4864F71B067620005DB302 /* Cedar-iOS */ = { isa = PBXNativeTarget; buildConfigurationList = AE48650F1B067621005DB302 /* Build configuration list for PBXNativeTarget "Cedar-iOS" */; buildPhases = ( AE4864F51B067620005DB302 /* Headers */, AE4864F31B067620005DB302 /* Sources */, 344077C51BA76D1700037486 /* Set Git SHA on Framework */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-iOS"; productName = "Cedar-iOS-Framework"; productReference = AE4864F81B067620005DB302 /* Cedar.framework */; productType = "com.apple.product-type.framework"; }; AEEE1FB511DC271300029872 /* Cedar-OSX */ = { isa = PBXNativeTarget; buildConfigurationList = AEEE1FBC11DC271300029872 /* Build configuration list for PBXNativeTarget "Cedar-OSX" */; buildPhases = ( AEEE1FB111DC271300029872 /* Headers */, AEEE1FB311DC271300029872 /* Sources */, 344077C11BA74D7B00037486 /* Set Git SHA on Framework */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-OSX"; productName = Cedar; productReference = AEEE1FB611DC271300029872 /* Cedar.framework */; productType = "com.apple.product-type.framework"; }; AEEE218511DC28E200029872 /* Cedar-OSX Specs */ = { isa = PBXNativeTarget; buildConfigurationList = AEEE21CA11DC292600029872 /* Build configuration list for PBXNativeTarget "Cedar-OSX Specs" */; buildPhases = ( AEEE218311DC28E200029872 /* Sources */, AEEE218411DC28E200029872 /* Frameworks */, ); buildRules = ( ); dependencies = ( AEEE218B11DC28E700029872 /* PBXTargetDependency */, ); name = "Cedar-OSX Specs"; productName = Specs; productReference = AEEE218611DC28E200029872 /* Cedar-OSX Specs */; productType = "com.apple.product-type.tool"; }; AEEE222811DC2B0600029872 /* Cedar-iOS StaticLib */ = { isa = PBXNativeTarget; buildConfigurationList = AEEE223011DC2B1300029872 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticLib" */; buildPhases = ( AEEE222611DC2B0600029872 /* Sources */, ); buildRules = ( ); dependencies = ( ); name = "Cedar-iOS StaticLib"; productName = "Cedar-StaticLib"; productReference = AEEE222911DC2B0600029872 /* libCedar.a */; productType = "com.apple.product-type.library.static"; }; AEEE227511DC2CF900029872 /* Cedar-iOS StaticLib Specs */ = { isa = PBXNativeTarget; buildConfigurationList = AEEE227B11DC2CF900029872 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticLib Specs" */; buildPhases = ( AEEE227211DC2CF900029872 /* Resources */, AEEE227311DC2CF900029872 /* Sources */, AEEE227411DC2CF900029872 /* Frameworks */, ); buildRules = ( ); dependencies = ( AE4865A31B067F53005DB302 /* PBXTargetDependency */, ); name = "Cedar-iOS StaticLib Specs"; productName = iPhoneSpecs; productReference = AEEE227611DC2CF900029872 /* Cedar-iOS StaticLib Specs.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ AEEE1FA611DC26EA00029872 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; LastTestingUpgradeCheck = 0700; LastUpgradeCheck = 0720; ORGANIZATIONNAME = Pivotal; TargetAttributes = { 1F45A3C8180E4796003C1E36 = { TestTargetID = 96B5F9F5144A81A7000A6A5D; }; 346261DE1B995239002CAEBD = { CreatedOnToolsVersion = 7.0; }; 346262771B99C1DB002CAEBD = { CreatedOnToolsVersion = 7.0; }; 346262831B99C1DC002CAEBD = { CreatedOnToolsVersion = 7.0; }; 34D7C3C91BB9747400E8E523 = { CreatedOnToolsVersion = 7.1; }; 34D7C4681BB9B71600E8E523 = { CreatedOnToolsVersion = 7.1; }; AE03FBE81B06C33B00013784 = { CreatedOnToolsVersion = 6.3.1; }; AE248F9719DCD52500092C14 = { CreatedOnToolsVersion = 6.0.1; }; AE248FA919DCD52500092C14 = { CreatedOnToolsVersion = 6.0.1; TestTargetID = AE248F9719DCD52500092C14; }; AE4864F71B067620005DB302 = { CreatedOnToolsVersion = 6.3.1; }; }; }; buildConfigurationList = AEEE1FA911DC26EA00029872 /* Build configuration list for PBXProject "Cedar" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, Japanese, French, German, en, Base, ); mainGroup = AEEE1FA411DC26EA00029872; productRefGroup = AEEE1FB711DC271300029872 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( AEEE1FB511DC271300029872 /* Cedar-OSX */, AE4864F71B067620005DB302 /* Cedar-iOS */, 346261DE1B995239002CAEBD /* Cedar-watchOS */, 34D7C3C91BB9747400E8E523 /* Cedar-tvOS */, AEEE222811DC2B0600029872 /* Cedar-iOS StaticLib */, AEEE224B11DC2BBB00029872 /* Cedar-iOS StaticFramework */, AEEE218511DC28E200029872 /* Cedar-OSX Specs */, 96A07EEE13F276640021974D /* Cedar-OSX FocusedSpecs */, AE03FBE81B06C33B00013784 /* Cedar-iOS Specs */, AEEE227511DC2CF900029872 /* Cedar-iOS StaticLib Specs */, AE02E7E3184EABCD00414F19 /* Cedar-iOS StaticFrameworkSpecs */, AE248F9719DCD52500092C14 /* Cedar-OSX HostApp */, 96B5F9F5144A81A7000A6A5D /* Cedar-iOS HostApp */, 34852D131BBE35FF0072D249 /* Cedar-watchOS HostApp */, AE248FA919DCD52500092C14 /* Cedar-OSX SpecBundle */, 1F45A3C8180E4796003C1E36 /* Cedar-iOS SpecBundle */, 346262771B99C1DB002CAEBD /* Cedar-watchOS Specs */, 346262831B99C1DC002CAEBD /* Cedar-watchOS Specs Extension */, 34D7C4681BB9B71600E8E523 /* Cedar-tvOS SpecBundle */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 346262761B99C1DB002CAEBD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 34A848591B9A4A2E00396A09 /* Interface.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 346262821B99C1DC002CAEBD /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 34FD462B1B99D1FD00257186 /* edward.jpg in Resources */, 34FD462C1B99D1FD00257186 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 34D7C4671BB9B71600E8E523 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 34D7C4731BB9B79500E8E523 /* edward.jpg in Resources */, 34D7C4741BB9B79500E8E523 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 96B5F9F4144A81A7000A6A5D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 96D34482144A82DB00352C4A /* DummyView.xib in Resources */, 34852D261BBE38EE0072D249 /* Default-568h@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE03FBE71B06C33B00013784 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( AEB9B2CC1B23F5FB003E4728 /* edward.jpg in Resources */, AEB9B2CB1B23F5DF003E4728 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE227211DC2CF900029872 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( AEEF361019DF27E400794484 /* edward.jpg in Resources */, AEEF360E19DF24AB00794484 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 344077C11BA74D7B00037486 /* Set Git SHA on Framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Set Git SHA on Framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/usr/bin/env ruby scripts/set_git_sha_on_framework.rb"; }; 344077C41BA7544F00037486 /* Set Git SHA on Framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Set Git SHA on Framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "PLIST_PATH=../${CONFIGURATION}-iphoneuniversal/${PRODUCT_NAME}.framework/Resources/Info.plist\nINFOPLIST_PATH=${PLIST_PATH} /usr/bin/env ruby scripts/set_git_sha_on_framework.rb"; }; 344077C51BA76D1700037486 /* Set Git SHA on Framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Set Git SHA on Framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/usr/bin/env ruby scripts/set_git_sha_on_framework.rb"; }; 3444602A190CC3320076655A /* Copy Info.plist to framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Copy Info.plist to framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "cp \"${SRCROOT}/Cedar-Info.plist\" \"${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal/${PRODUCT_NAME}.framework/Resources/Info.plist\""; }; 34D7C3BF1BB9703400E8E523 /* Set Git SHA on Framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Set Git SHA on Framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/usr/bin/env ruby scripts/set_git_sha_on_framework.rb"; }; 34D7C4641BB9B66600E8E523 /* Set Git SHA on Framework */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Set Git SHA on Framework"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/usr/bin/env ruby scripts/set_git_sha_on_framework.rb"; }; AEEE225511DC2BD700029872 /* Build architecture-specific static libs */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Build architecture-specific static libs"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target \"${PROJECT_NAME}-iOS StaticLib\" -configuration ${CONFIGURATION} clean build ARCHS=\"i386 x86_64\" SYMROOT=\"${SYMROOT}\" ONLY_ACTIVE_ARCH=NO\nxcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target \"${PROJECT_NAME}-iOS StaticLib\" -configuration ${CONFIGURATION} clean build ARCHS=\"armv7 armv7s arm64\" SYMROOT=\"${SYMROOT}\" ONLY_ACTIVE_ARCH=NO"; }; AEEE225A11DC2C0200029872 /* Build universal static lib */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Build universal static lib"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "SIMULATOR_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a\" &&\n\tDEVICE_LIBRARY_PATH=\"${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a\" &&\n\tUNIVERSAL_LIBRARY_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal\" &&\n\tUNIVERSAL_LIBRARY_PATH=\"${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}\" &&\n\tFRAMEWORK=\"${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}.framework\" &&\n\n# Create framework directory structure.\n\trm -rf \"${FRAMEWORK}\" &&\n\tmkdir -p \"${UNIVERSAL_LIBRARY_DIR}\" &&\n\tmkdir -p \"${FRAMEWORK}/Versions/A/Headers\" &&\n\tmkdir -p \"${FRAMEWORK}/Versions/A/Resources\" &&\n\n# Generate universal binary from desktop, device, and simulator builds.\n\tlipo \"${SIMULATOR_LIBRARY_PATH}\" \"${DEVICE_LIBRARY_PATH}\" -create -output \"${UNIVERSAL_LIBRARY_PATH}\" &&\n\n# Move files to appropriate locations in framework paths.\n\tcp \"${UNIVERSAL_LIBRARY_PATH}\" \"${FRAMEWORK}/Versions/A\" &&\n\tcd \"${FRAMEWORK}/Versions\" &&\n\tln -s \"A\" \"Current\" &&\n cd \"${FRAMEWORK}\" &&\n\tln -s \"Versions/Current/Headers\" \"Headers\" &&\n\tln -s \"Versions/Current/Resources\" \"Resources\" &&\n\tln -s \"Versions/Current/${PRODUCT_NAME}\" \"${PRODUCT_NAME}\"\n"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 1F45A3CD180E4796003C1E36 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F71C2F391D3DADD0003B37DC /* CedarTestSpecBuilder.m in Sources */, F7BBE7D31B43A852009547F0 /* CedarDoubleSharedExamples.mm in Sources */, F78FDA161B43AA8C0054C768 /* CedarNiceFakeSharedExamples.mm in Sources */, 1F45A3CE180E4796003C1E36 /* SpecBundleApplicationTests.mm in Sources */, AE34722A19C118C9005CA6F1 /* SpecSpec.mm in Sources */, F7C9BBF01D3E83F100B694C0 /* CDRSpecRunSpec.mm in Sources */, F78FDA181B43AA8F0054C768 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, F78FDA1D1B43ABBC0054C768 /* ExpectFailureWithMessage.mm in Sources */, 1F45A3E3180E4A1C003C1E36 /* SpecBundleApplicationTestsWithXCTest.m in Sources */, AE34723019C124CE005CA6F1 /* CDRExampleGroupSpec.mm in Sources */, AE34723719C12534005CA6F1 /* FibonacciCalculator.m in Sources */, AE34722F19C124CE005CA6F1 /* CDRExampleSpec.mm in Sources */, F7A225DC1B43A8FB006231CC /* FooSuperclass.m in Sources */, 1F45A3D0180E4796003C1E36 /* CDRSymbolicatorSpec.mm in Sources */, AE34723919C12588005CA6F1 /* SimpleKeyValueObserver.m in Sources */, F78FDA1B1B43AB540054C768 /* SimpleIncrementer.m in Sources */, 34AF814F1C53A06500DB5249 /* TestReporter.m in Sources */, AE34723419C124D6005CA6F1 /* ObjCHeadersSpec.mm in Sources */, 34322B0C1BA7471B00D0CFBD /* TestObservationHelper.m in Sources */, AE34723D19C22547005CA6F1 /* CDRDefaultReporterSpec.mm in Sources */, AE34724619C225A1005CA6F1 /* CDRXCTestSuiteSpec.mm in Sources */, F78FDA1A1B43AA930054C768 /* HaveReceivedSpec.mm in Sources */, AE34722819C11872005CA6F1 /* CDRHooksSpec.mm in Sources */, 1F45A3D1180E4796003C1E36 /* CDRSpecFailureSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 346261DA1B995239002CAEBD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 346262461B9954E0002CAEBD /* CDRClassFake.mm in Sources */, F7C9BBF91D3E860100B694C0 /* CDRStateTracker.m in Sources */, 346262701B99569B002CAEBD /* CDRSpecHelper.m in Sources */, 346262451B9954E0002CAEBD /* CDRSpy.mm in Sources */, 346262691B99569B002CAEBD /* CDRExampleGroup.m in Sources */, 346262521B9954E4002CAEBD /* AnyInstanceConformingToProtocolArgument.mm in Sources */, 346262551B99567D002CAEBD /* StringifiersBase.mm in Sources */, 3462625F1B99568F002CAEBD /* CDRReportDispatcher.m in Sources */, 346262511B9954E4002CAEBD /* AnyInstanceOfClassArgument.mm in Sources */, 34D7C3C11BB970F100E8E523 /* CDRSpecRun.m in Sources */, 346262721B99569B002CAEBD /* CDRTypeUtilities.m in Sources */, 3462626F1B99569B002CAEBD /* CDRSpecFailure.m in Sources */, 346262581B995683002CAEBD /* ConformTo.mm in Sources */, 3462626C1B99569B002CAEBD /* CDRRuntimeUtilities.m in Sources */, 346262531B9954EA002CAEBD /* NSInvocation+Cedar.m in Sources */, 346262591B995689002CAEBD /* CDROTestNamer.m in Sources */, 3462624B1B9954E0002CAEBD /* StubbedMethod.mm in Sources */, 346262641B995696002CAEBD /* CDRXCTestObserver.m in Sources */, 346262651B995696002CAEBD /* CDRXCTestSuite.m in Sources */, 3462626E1B99569B002CAEBD /* CDRSpec.m in Sources */, 346262621B995696002CAEBD /* CDRSpec+XCTestSupport.m in Sources */, 346262491B9954E0002CAEBD /* CedarDouble.mm in Sources */, 346262611B99568F002CAEBD /* CDRBufferedDefaultReporter.m in Sources */, 346262541B9954EA002CAEBD /* NSMethodSignature+Cedar.m in Sources */, 34D7C3C01BB970DF00E8E523 /* CDRXCTestFunctions.m in Sources */, 3462626A1B99569B002CAEBD /* CDRFunctions.m in Sources */, 346262671B99569B002CAEBD /* CDRExample.m in Sources */, 346262681B99569B002CAEBD /* CDRExampleBase.m in Sources */, 3462625A1B995689002CAEBD /* CDRSlowTestStatistics.m in Sources */, 3462624C1B9954E0002CAEBD /* InvocationMatcher.mm in Sources */, 346262471B9954E0002CAEBD /* CedarDoubleImpl.mm in Sources */, 3462624D1B9954E0002CAEBD /* HaveReceived.mm in Sources */, 3462625D1B99568F002CAEBD /* CDRJUnitXMLReporter.m in Sources */, 346262501B9954E4002CAEBD /* AnyArgument.mm in Sources */, 3462625B1B99568F002CAEBD /* CDRColorizedReporter.m in Sources */, 3462625E1B99568F002CAEBD /* CDROTestReporter.m in Sources */, 346262481B9954E0002CAEBD /* CDRFake.mm in Sources */, 3462625C1B99568F002CAEBD /* CDRDefaultReporter.m in Sources */, 346262661B995696002CAEBD /* NSInvocation+CDRXExample.m in Sources */, 346262601B99568F002CAEBD /* CDRTeamCityReporter.m in Sources */, 346262571B995683002CAEBD /* RespondTo.mm in Sources */, 346262631B995696002CAEBD /* CDRXCTestCase.m in Sources */, 346262561B995683002CAEBD /* RaiseException.mm in Sources */, 346262711B99569B002CAEBD /* CDRSymbolicator.m in Sources */, 346262441B9954E0002CAEBD /* CDRProtocolFake.mm in Sources */, 3462624A1B9954E0002CAEBD /* RejectedMethod.mm in Sources */, 3462626B1B99569B002CAEBD /* CDRTestBundleRunner.m in Sources */, 3462626D1B99569B002CAEBD /* CDRSharedExampleGroupPool.m in Sources */, 3462624F1B9954E4002CAEBD /* AnyInstanceArgument.mm in Sources */, 3462624E1B9954E0002CAEBD /* CDRSpyInfo.mm in Sources */, 346262731B99569B002CAEBD /* CDRNil.m in Sources */, F7C9BC041D45E19B00B694C0 /* CDRRunState.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 346262801B99C1DC002CAEBD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 34FD463B1B99D25000257186 /* ObjectWithValueEquality.m in Sources */, 34D181A11BC7F0FF0087EC0D /* BlockMatcher_ARCSpecSpec.mm in Sources */, 34FD465B1B99D2E300257186 /* CedarNiceFakeSharedExamples.mm in Sources */, F71C2F3A1D3DADD1003B37DC /* CedarTestSpecBuilder.m in Sources */, 34FD46471B99D2B000257186 /* BeNilSpec.mm in Sources */, 34FD465C1B99D2E300257186 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, 34FD46531B99D2B900257186 /* UIKitEqualSpec.mm in Sources */, 34FD46451B99D2B000257186 /* BeLTESpec.mm in Sources */, 34FD46521B99D2B500257186 /* ContainSpec.mm in Sources */, 34FD463C1B99D25200257186 /* FooSuperclass.m in Sources */, 34FD46331B99D22D00257186 /* ObjectWithForwardingTarget.m in Sources */, 34D181A01BC7F0FF0087EC0D /* BlockMatcherSpec.mm in Sources */, 34FD464E1B99D2B000257186 /* MutableEqualSpec.mm in Sources */, 34FD463A1B99D24900257186 /* ExampleWithPublicRunDates.mm in Sources */, 34FD464D1B99D2B000257186 /* ExistSpec.mm in Sources */, 34FD46321B99D22A00257186 /* FibonacciCalculator.m in Sources */, 34FD46651B99D2F200257186 /* SpecSpec.mm in Sources */, 34FD464C1B99D2B000257186 /* EqualSpec.mm in Sources */, 34FD46421B99D2B000257186 /* BeGTESpec.mm in Sources */, 34FD46391B99D24400257186 /* GDataXMLNode.m in Sources */, 34FD462F1B99D21300257186 /* CDROTestReporterSpec.mm in Sources */, 34FD46561B99D2E300257186 /* CDRClassFakeSpec.mm in Sources */, 34FD46611B99D2F200257186 /* CDRSymbolicatorSpec.mm in Sources */, 34FD462E1B99D21300257186 /* CDRJUnitXMLReporterSpec.mm in Sources */, 34FD46311B99D22700257186 /* ArgumentReleaser.m in Sources */, 34FD46371B99D23800257186 /* SimpleIncrementer.m in Sources */, 34FD462D1B99D21300257186 /* CDRDefaultReporterSpec.mm in Sources */, 34FD46631B99D2F200257186 /* CDRHooksSpec.mm in Sources */, 34FD465A1B99D2E300257186 /* CedarDoubleSharedExamples.mm in Sources */, 34FD46501B99D2B000257186 /* RespondToSpec.mm in Sources */, 34FD46661B99D2F900257186 /* CDRTypeUtilitiesSpec.mm in Sources */, 34FD46411B99D2B000257186 /* BeGreaterThanSpec.mm in Sources */, 34FD46461B99D2B000257186 /* BeNil_ARCSpec.mm in Sources */, 34FD465E1B99D2F200257186 /* CDRSpecSpec.mm in Sources */, F7C8F30B1BC63A000088069D /* ContainSubsetSpec.mm in Sources */, 34FD46491B99D2B000257186 /* BeSameInstanceAsSpec.mm in Sources */, 34FD46351B99D23300257186 /* ObjectWithWeakDelegate.m in Sources */, 34FD46431B99D2B000257186 /* BeInstanceOfSpec.mm in Sources */, 34FD46641B99D2F200257186 /* ObjCHeadersSpec.mm in Sources */, 34FD46361B99D23500257186 /* ObjectWithCollections.m in Sources */, 34FD46511B99D2B500257186 /* BeEmptySpec.mm in Sources */, 34FD46581B99D2E300257186 /* CDRSpySpec.mm in Sources */, 34FD465D1B99D2E300257186 /* HaveReceivedSpec.mm in Sources */, 34FD46441B99D2B000257186 /* BeLessThanSpec.mm in Sources */, 34FD464A1B99D2B000257186 /* BeTruthySpec.mm in Sources */, 34FD465F1B99D2F200257186 /* CDRExampleSpec.mm in Sources */, 34FD46601B99D2F200257186 /* CDRExampleGroupSpec.mm in Sources */, 34FD46341B99D23000257186 /* ObjectWithProperty.m in Sources */, 34FD464F1B99D2B000257186 /* RaiseExceptionSpec.mm in Sources */, 34FD46381B99D23C00257186 /* SimpleKeyValueObserver.m in Sources */, 3462628E1B99C1DC002CAEBD /* ExtensionDelegate.mm in Sources */, 34FD46541B99D2C100257186 /* ShouldSyntaxSpec.mm in Sources */, 34FD46621B99D2F200257186 /* CDRSpecFailureSpec.mm in Sources */, 34FD46551B99D2CD00257186 /* ExpectFailureWithMessage.mm in Sources */, 34FD464B1B99D2B000257186 /* ConformToSpec.mm in Sources */, 34FD463D1B99D25600257186 /* DeallocNotifier.m in Sources */, 34FD463F1B99D2B000257186 /* BeCloseToSpec.mm in Sources */, 345B1E8C1C31D4B4009BB77D /* SwiftSpec.swift in Sources */, 34FD46481B99D2B000257186 /* BeSameInstanceAs_ARCSpec.mm in Sources */, 34FD46671B99D2F900257186 /* CDRNilSpec.mm in Sources */, 34FD46591B99D2E300257186 /* CedarDoubleARCSharedExamples.mm in Sources */, F7C9BBF11D3E83F200B694C0 /* CDRSpecRunSpec.mm in Sources */, 34FD46401B99D2B000257186 /* BeFalsySpec.mm in Sources */, 34FD46571B99D2E300257186 /* CDRProtocolFakeSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 34852D141BBE35FF0072D249 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 34852D151BBE35FF0072D249 /* main.m in Sources */, 34852D161BBE35FF0072D249 /* iOSHostAppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 34D7C3C51BB9747400E8E523 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 34D7C3FF1BB9B52E00E8E523 /* CDRSpec.m in Sources */, 34D7C3D71BB9B4D600E8E523 /* CDRSpy.mm in Sources */, 34D7C3F01BB9B52200E8E523 /* CDRTeamCityReporter.m in Sources */, 34D7C3D21BB9B4D600E8E523 /* AnyInstanceArgument.mm in Sources */, 34D7C3F91BB9B52E00E8E523 /* CDRExampleBase.m in Sources */, F7C9BBFA1D3E860200B694C0 /* CDRStateTracker.m in Sources */, 34D7C3D51BB9B4D600E8E523 /* AnyInstanceConformingToProtocolArgument.mm in Sources */, 34D7C4031BB9B52E00E8E523 /* CDRTypeUtilities.m in Sources */, 34D7C3DA1BB9B4D600E8E523 /* CDRFake.mm in Sources */, 34D7C3E11BB9B4DD00E8E523 /* NSInvocation+Cedar.m in Sources */, 34D7C4021BB9B52E00E8E523 /* CDRSymbolicator.m in Sources */, 34D7C3EA1BB9B51E00E8E523 /* CDRSlowTestStatistics.m in Sources */, 34D7C3EC1BB9B52200E8E523 /* CDRDefaultReporter.m in Sources */, 34D7C3D31BB9B4D600E8E523 /* AnyArgument.mm in Sources */, 34D7C3E81BB9B51900E8E523 /* ConformTo.mm in Sources */, 34D7C3E01BB9B4D600E8E523 /* CDRSpyInfo.mm in Sources */, 34D7C3F61BB9B52700E8E523 /* NSInvocation+CDRXExample.m in Sources */, 34D7C3F11BB9B52200E8E523 /* CDRBufferedDefaultReporter.m in Sources */, 34D7C3FC1BB9B52E00E8E523 /* CDRTestBundleRunner.m in Sources */, 34D7C3E21BB9B4DD00E8E523 /* NSMethodSignature+Cedar.m in Sources */, 34D7C3D61BB9B4D600E8E523 /* CDRProtocolFake.mm in Sources */, 34D7C3DE1BB9B4D600E8E523 /* InvocationMatcher.mm in Sources */, 34D7C3F81BB9B52E00E8E523 /* CDRExample.m in Sources */, 34D7C3F21BB9B52700E8E523 /* CDRSpec+XCTestSupport.m in Sources */, 34D7C3E61BB9B51900E8E523 /* RaiseException.mm in Sources */, 34D7C3F71BB9B52700E8E523 /* CDRXCTestFunctions.m in Sources */, 34D7C3DB1BB9B4D600E8E523 /* CedarDouble.mm in Sources */, 34D7C3F41BB9B52700E8E523 /* CDRXCTestSuite.m in Sources */, 34D7C3ED1BB9B52200E8E523 /* CDRJUnitXMLReporter.m in Sources */, 34D7C3EB1BB9B52200E8E523 /* CDRColorizedReporter.m in Sources */, 34D7C3E51BB9B51600E8E523 /* StringifiersBase.mm in Sources */, 34D7C3EF1BB9B52200E8E523 /* CDRReportDispatcher.m in Sources */, 34D7C3FA1BB9B52E00E8E523 /* CDRExampleGroup.m in Sources */, 34D7C4051BB9B52E00E8E523 /* CDRSpecRun.m in Sources */, 34D7C3D81BB9B4D600E8E523 /* CDRClassFake.mm in Sources */, 34D7C3D91BB9B4D600E8E523 /* CedarDoubleImpl.mm in Sources */, 34D7C3F31BB9B52700E8E523 /* CDRXCTestCase.m in Sources */, 34D7C3DF1BB9B4D600E8E523 /* HaveReceived.mm in Sources */, 34D7C3FE1BB9B52E00E8E523 /* CDRSharedExampleGroupPool.m in Sources */, 34D7C3FD1BB9B52E00E8E523 /* CDRRuntimeUtilities.m in Sources */, 34D7C3E71BB9B51900E8E523 /* RespondTo.mm in Sources */, 34D7C3D41BB9B4D600E8E523 /* AnyInstanceOfClassArgument.mm in Sources */, 34D7C3DD1BB9B4D600E8E523 /* StubbedMethod.mm in Sources */, 34D7C3E41BB9B51100E8E523 /* CedarApplicationDelegate.m in Sources */, 34D7C4001BB9B52E00E8E523 /* CDRSpecFailure.m in Sources */, 34D7C3E91BB9B51E00E8E523 /* CDROTestNamer.m in Sources */, 34D7C3DC1BB9B4D600E8E523 /* RejectedMethod.mm in Sources */, F7C9BC051D45E19B00B694C0 /* CDRRunState.m in Sources */, 34D7C3EE1BB9B52200E8E523 /* CDROTestReporter.m in Sources */, 34D7C3F51BB9B52700E8E523 /* CDRXCTestObserver.m in Sources */, 34D7C3E31BB9B51100E8E523 /* NSBundle+MainBundleHijack.m in Sources */, 34D7C4011BB9B52E00E8E523 /* CDRSpecHelper.m in Sources */, 34D7C3FB1BB9B52E00E8E523 /* CDRFunctions.m in Sources */, 34D7C4041BB9B52E00E8E523 /* CDRNil.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 34D7C4651BB9B71600E8E523 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 345B1E891C31D495009BB77D /* SwiftSpec.swift in Sources */, 34D7C4AC1BB9C6C400E8E523 /* CDRExampleGroupSpec.mm in Sources */, 34D7C4851BB9C62400E8E523 /* DeallocNotifier.m in Sources */, 34D7C4891BB9C67400E8E523 /* CDRSpyiOSSpec.mm in Sources */, 34D7C4AF1BB9C6C400E8E523 /* CDRHooksSpec.mm in Sources */, 34D7C48D1BB9C67C00E8E523 /* BeGTESpec.mm in Sources */, 34D7C47A1BB9B7AD00E8E523 /* FibonacciCalculator.m in Sources */, 34D7C4961BB9C67C00E8E523 /* ConformToSpec.mm in Sources */, 34D7C4901BB9C67C00E8E523 /* BeLTESpec.mm in Sources */, 34D7C49A1BB9C67C00E8E523 /* RaiseExceptionSpec.mm in Sources */, 34D7C4991BB9C67C00E8E523 /* MutableEqualSpec.mm in Sources */, 34D7C4981BB9C67C00E8E523 /* ExistSpec.mm in Sources */, F7C8F30C1BC63A000088069D /* ContainSubsetSpec.mm in Sources */, 34D7C4841BB9C61E00E8E523 /* FooSuperclass.m in Sources */, 34D7C4811BB9C61300E8E523 /* GDataXMLNode.m in Sources */, 34D7C4831BB9C61A00E8E523 /* ObjectWithValueEquality.m in Sources */, 34D7C48A1BB9C67C00E8E523 /* BeCloseToSpec.mm in Sources */, 34D7C4A81BB9C69A00E8E523 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, 34D7C4A41BB9C69A00E8E523 /* CDRSpySpec.mm in Sources */, 34D7C4801BB9C60D00E8E523 /* SimpleKeyValueObserver.m in Sources */, 34D7C4881BB9C67100E8E523 /* WeakReferenceCompatibilitySpec.mm in Sources */, 34D1819F1BC7F0FD0087EC0D /* BlockMatcher_ARCSpecSpec.mm in Sources */, 34D7C4AB1BB9C6C400E8E523 /* CDRExampleSpec.mm in Sources */, 34D7C4761BB9B79D00E8E523 /* CDRJUnitXMLReporterSpec.mm in Sources */, 34D7C4771BB9B79D00E8E523 /* CDROTestReporterSpec.mm in Sources */, 34D7C4941BB9C67C00E8E523 /* BeSameInstanceAsSpec.mm in Sources */, 34D7C4AA1BB9C6C400E8E523 /* CDRSpecSpec.mm in Sources */, 34D7C4871BB9C66000E8E523 /* CedarApplicationDelegateSpec.mm in Sources */, 34D7C4AD1BB9C6C400E8E523 /* CDRSymbolicatorSpec.mm in Sources */, F7C9BBF21D3E83F200B694C0 /* CDRSpecRunSpec.mm in Sources */, 34D7C4A11BB9C69100E8E523 /* ExpectFailureWithMessage.mm in Sources */, 34D7C4A61BB9C69A00E8E523 /* CedarDoubleSharedExamples.mm in Sources */, 34D7C4B31BB9C6C700E8E523 /* CDRNilSpec.mm in Sources */, 34D7C4911BB9C67C00E8E523 /* BeNil_ARCSpec.mm in Sources */, 34D7C49F1BB9C68900E8E523 /* UIKitContainSpec.mm in Sources */, 34D7C48C1BB9C67C00E8E523 /* BeGreaterThanSpec.mm in Sources */, 34D7C4A71BB9C69A00E8E523 /* CedarNiceFakeSharedExamples.mm in Sources */, 34D7C49E1BB9C68900E8E523 /* UIKitEqualSpec.mm in Sources */, 34D7C47E1BB9C60700E8E523 /* ObjectWithCollections.m in Sources */, 34D7C47B1BB9B7B000E8E523 /* ObjectWithForwardingTarget.m in Sources */, 34D7C4A31BB9C69A00E8E523 /* CDRProtocolFakeSpec.mm in Sources */, 34D7C4751BB9B79D00E8E523 /* CDRDefaultReporterSpec.mm in Sources */, 34D7C4A21BB9C69A00E8E523 /* CDRClassFakeSpec.mm in Sources */, 34D7C4921BB9C67C00E8E523 /* BeNilSpec.mm in Sources */, 34D7C48E1BB9C67C00E8E523 /* BeInstanceOfSpec.mm in Sources */, 34D7C4A51BB9C69A00E8E523 /* CedarDoubleARCSharedExamples.mm in Sources */, 34D7C4B41BB9C75D00E8E523 /* TestObservationHelper.m in Sources */, 34D7C4781BB9B7A500E8E523 /* ARCViewController.m in Sources */, 34D7C4821BB9C61700E8E523 /* ExampleWithPublicRunDates.mm in Sources */, 34D7C4B21BB9C6C700E8E523 /* CDRTypeUtilitiesSpec.mm in Sources */, 34D7C4861BB9C65700E8E523 /* CDRXCTestSuiteSpec.mm in Sources */, 34D7C4931BB9C67C00E8E523 /* BeSameInstanceAs_ARCSpec.mm in Sources */, 34D7C47F1BB9C60A00E8E523 /* SimpleIncrementer.m in Sources */, 34AF81501C53A06600DB5249 /* TestReporter.m in Sources */, 34D7C4B11BB9C6C400E8E523 /* SpecSpec.mm in Sources */, 34D7C47C1BB9C5FD00E8E523 /* ObjectWithProperty.m in Sources */, 34D1819E1BC7F0FD0087EC0D /* BlockMatcherSpec.mm in Sources */, 34D7C49B1BB9C67C00E8E523 /* RespondToSpec.mm in Sources */, 34D7C4791BB9B7AB00E8E523 /* ArgumentReleaser.m in Sources */, 34D7C49C1BB9C68100E8E523 /* BeEmptySpec.mm in Sources */, 34D7C4971BB9C67C00E8E523 /* EqualSpec.mm in Sources */, 34D7C48F1BB9C67C00E8E523 /* BeLessThanSpec.mm in Sources */, 345B1E911C31DA70009BB77D /* XCTAssertSpec.swift in Sources */, 34D7C47D1BB9C60100E8E523 /* ObjectWithWeakDelegate.m in Sources */, 34D7C4B01BB9C6C400E8E523 /* ObjCHeadersSpec.mm in Sources */, 34D7C49D1BB9C68100E8E523 /* ContainSpec.mm in Sources */, 34D7C48B1BB9C67C00E8E523 /* BeFalsySpec.mm in Sources */, 34D7C4A91BB9C69A00E8E523 /* HaveReceivedSpec.mm in Sources */, 34D7C4A01BB9C68E00E8E523 /* ShouldSyntaxSpec.mm in Sources */, F71C2F3B1D3DADD1003B37DC /* CedarTestSpecBuilder.m in Sources */, 34D7C4951BB9C67C00E8E523 /* BeTruthySpec.mm in Sources */, 34D7C4AE1BB9C6C400E8E523 /* CDRSpecFailureSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 96A07EF313F276640021974D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 96A07F0B13F276B10021974D /* FocusedSpec.m in Sources */, 96A07F0F13F27F2F0021974D /* main.mm in Sources */, AE0F355019E89BC400B9F116 /* SimpleIncrementer.m in Sources */, 96A07F1113F283E40021974D /* FocusedSpec2.m in Sources */, AEE0665717315C20003CA143 /* CedarNiceFakeSharedExamples.mm in Sources */, AEE0665A17315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 96B5F9F2144A81A7000A6A5D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 96B5FA05144A81A8000A6A5D /* main.m in Sources */, 96B5FA08144A81A8000A6A5D /* iOSHostAppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE02E7E0184EABCD00414F19 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F71C2F381D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */, 346D1A9A1BBB3DDE00BECD4B /* main.mm in Sources */, AE02E83118526E9F00414F19 /* Cedar-iOSSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE03FBE51B06C33B00013784 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AE1937611B1AC22D008C8CD8 /* CedarDoubleSharedExamples.mm in Sources */, AE1937811B1AC4AC008C8CD8 /* ExpectFailureWithMessage.mm in Sources */, AE19376C1B1AC22D008C8CD8 /* SpecSpec.mm in Sources */, AE1937621B1AC22D008C8CD8 /* CedarNiceFakeSharedExamples.mm in Sources */, AE19379B1B1AC94D008C8CD8 /* UIKitContainSpec.mm in Sources */, AE1937681B1AC22D008C8CD8 /* CDRSymbolicatorSpec.mm in Sources */, 346D1A991BBB3DDD00BECD4B /* main.mm in Sources */, AE1937901B1AC94D008C8CD8 /* BeSameInstanceAsSpec.mm in Sources */, AE1937671B1AC22D008C8CD8 /* CDRExampleGroupSpec.mm in Sources */, AE19378D1B1AC94D008C8CD8 /* BeNil_ARCSpec.mm in Sources */, AE1937691B1AC22D008C8CD8 /* CDRSpecFailureSpec.mm in Sources */, AE19378F1B1AC94D008C8CD8 /* BeSameInstanceAs_ARCSpec.mm in Sources */, AE1937641B1AC22D008C8CD8 /* HaveReceivedSpec.mm in Sources */, AE19376F1B1AC22D008C8CD8 /* CDRNilSpec.mm in Sources */, AE1937751B1AC3DC008C8CD8 /* ObjectWithWeakDelegate.m in Sources */, AE19379F1B1ACAFB008C8CD8 /* CDROTestReporterSpec.mm in Sources */, AE19375D1B1AC22D008C8CD8 /* CDRClassFakeSpec.mm in Sources */, AE1937A21B1ACC26008C8CD8 /* ExampleWithPublicRunDates.mm in Sources */, AE1937781B1AC3DC008C8CD8 /* SimpleKeyValueObserver.m in Sources */, AE1937631B1AC22D008C8CD8 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, AE1937771B1AC3DC008C8CD8 /* SimpleIncrementer.m in Sources */, 346F64701B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */, AE1937871B1AC94D008C8CD8 /* BeFalsySpec.mm in Sources */, AE19375A1B1AC149008C8CD8 /* CDRDefaultReporterSpec.mm in Sources */, AE1937741B1AC3DC008C8CD8 /* ObjectWithProperty.m in Sources */, AE1937731B1AC3DC008C8CD8 /* ObjectWithForwardingTarget.m in Sources */, AE1937601B1AC22D008C8CD8 /* CedarDoubleARCSharedExamples.mm in Sources */, AE1937941B1AC94D008C8CD8 /* ExistSpec.mm in Sources */, AE19378E1B1AC94D008C8CD8 /* BeNilSpec.mm in Sources */, AE1937851B1AC919008C8CD8 /* CDRSpyiOSSpec.mm in Sources */, AE1937911B1AC94D008C8CD8 /* BeTruthySpec.mm in Sources */, AE19377C1B1AC3DC008C8CD8 /* DeallocNotifier.m in Sources */, AE1937931B1AC94D008C8CD8 /* EqualSpec.mm in Sources */, AE1937971B1AC94D008C8CD8 /* RespondToSpec.mm in Sources */, AE19379C1B1AC94D008C8CD8 /* ShouldSyntaxSpec.mm in Sources */, AE19379A1B1AC94D008C8CD8 /* UIKitEqualSpec.mm in Sources */, AE1937891B1AC94D008C8CD8 /* BeGTESpec.mm in Sources */, AE1937841B1AC90F008C8CD8 /* WeakReferenceCompatibilitySpec.mm in Sources */, F7C9BBEE1D3E83EB00B694C0 /* CDRSpecRunSpec.mm in Sources */, AE19375E1B1AC22D008C8CD8 /* CDRProtocolFakeSpec.mm in Sources */, AE1937961B1AC94D008C8CD8 /* RaiseExceptionSpec.mm in Sources */, AE19378B1B1AC94D008C8CD8 /* BeLessThanSpec.mm in Sources */, AE19377B1B1AC3DC008C8CD8 /* FooSuperclass.m in Sources */, F7C8F3061BC63A000088069D /* ContainSubsetSpec.mm in Sources */, AE1937861B1AC94D008C8CD8 /* BeCloseToSpec.mm in Sources */, AE1937661B1AC22D008C8CD8 /* CDRExampleSpec.mm in Sources */, AE1937701B1AC3DC008C8CD8 /* ARCViewController.m in Sources */, AE1937721B1AC3DC008C8CD8 /* FibonacciCalculator.m in Sources */, AE19378A1B1AC94D008C8CD8 /* BeInstanceOfSpec.mm in Sources */, AE1937881B1AC94D008C8CD8 /* BeGreaterThanSpec.mm in Sources */, AE1937651B1AC22D008C8CD8 /* CDRSpecSpec.mm in Sources */, 34C95F551C2E57A90055F089 /* SwiftSpec.swift in Sources */, AE1937921B1AC94D008C8CD8 /* ConformToSpec.mm in Sources */, AE19378C1B1AC94D008C8CD8 /* BeLTESpec.mm in Sources */, AE0BF0711B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */, AE1937A31B1ACC2E008C8CD8 /* GDataXMLNode.m in Sources */, F71C2F361D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */, AE19379E1B1ACAFB008C8CD8 /* CDRJUnitXMLReporterSpec.mm in Sources */, AE1937981B1AC94D008C8CD8 /* BeEmptySpec.mm in Sources */, AE19376B1B1AC22D008C8CD8 /* ObjCHeadersSpec.mm in Sources */, AE19376E1B1AC22D008C8CD8 /* CDRTypeUtilitiesSpec.mm in Sources */, AE1937711B1AC3DC008C8CD8 /* ArgumentReleaser.m in Sources */, AE19377A1B1AC3DC008C8CD8 /* ObjectWithValueEquality.m in Sources */, AE1937831B1AC90A008C8CD8 /* CedarApplicationDelegateSpec.mm in Sources */, AE1937951B1AC94D008C8CD8 /* MutableEqualSpec.mm in Sources */, AE19375F1B1AC22D008C8CD8 /* CDRSpySpec.mm in Sources */, AE1937991B1AC94D008C8CD8 /* ContainSpec.mm in Sources */, AE19376A1B1AC22D008C8CD8 /* CDRHooksSpec.mm in Sources */, AE1937761B1AC3DC008C8CD8 /* ObjectWithCollections.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE248F9419DCD52500092C14 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AE248F9D19DCD52500092C14 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE248FA619DCD52500092C14 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 345B1E921C31E644009BB77D /* ExpectFailureWithMessage.mm in Sources */, 34757E261BA4A48E0047BC8D /* TestObservationHelper.m in Sources */, 346D1A971BBB37F400BECD4B /* SpecBundleApplicationTestsWithXCTest.m in Sources */, 345B1E8F1C31DA6E009BB77D /* XCTAssertSpec.swift in Sources */, 34AF814E1C53339300DB5249 /* TestReporter.m in Sources */, 34C95F561C2F16900055F089 /* CDRXCTestSuiteSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AE4864F31B067620005DB302 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AE48656F1B067953005DB302 /* AnyInstanceArgument.mm in Sources */, AE4865701B067953005DB302 /* AnyArgument.mm in Sources */, AE4865711B067953005DB302 /* AnyInstanceOfClassArgument.mm in Sources */, AE4865721B067953005DB302 /* AnyInstanceConformingToProtocolArgument.mm in Sources */, AE4865731B067953005DB302 /* CDRProtocolFake.mm in Sources */, F7C9BBF81D3E860100B694C0 /* CDRStateTracker.m in Sources */, AE4865741B067953005DB302 /* CDRSpy.mm in Sources */, AE4865751B067953005DB302 /* CDRClassFake.mm in Sources */, AE4865761B067953005DB302 /* CedarDoubleImpl.mm in Sources */, AE4865771B067953005DB302 /* CDRFake.mm in Sources */, AE4865781B067953005DB302 /* CedarDouble.mm in Sources */, AE4865791B067953005DB302 /* RejectedMethod.mm in Sources */, AE48657A1B067953005DB302 /* StubbedMethod.mm in Sources */, AE48657B1B067953005DB302 /* InvocationMatcher.mm in Sources */, AE48657C1B067953005DB302 /* HaveReceived.mm in Sources */, AE48657D1B067953005DB302 /* CDRSpyInfo.mm in Sources */, AE48657E1B067953005DB302 /* NSInvocation+Cedar.m in Sources */, F7F4099D1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */, AE48657F1B067953005DB302 /* NSMethodSignature+Cedar.m in Sources */, AE4865801B067953005DB302 /* CDRSpec+XCTestSupport.m in Sources */, AE4865811B067953005DB302 /* CDRXCTestSuite.m in Sources */, AE4865821B067953005DB302 /* CDRXCTestCase.m in Sources */, 3492DA991BA670C10032B35A /* CDRXCTestFunctions.m in Sources */, AE4865831B067953005DB302 /* NSInvocation+CDRXExample.m in Sources */, AE4865841B067953005DB302 /* NSBundle+MainBundleHijack.m in Sources */, AE4865851B067953005DB302 /* CedarApplicationDelegate.m in Sources */, AE4865861B067954005DB302 /* StringifiersBase.mm in Sources */, AE4865871B067954005DB302 /* RaiseException.mm in Sources */, AE4865881B067954005DB302 /* RespondTo.mm in Sources */, AE4865891B067954005DB302 /* ConformTo.mm in Sources */, AE48658A1B067954005DB302 /* CDROTestNamer.m in Sources */, AE48658B1B067954005DB302 /* CDRSlowTestStatistics.m in Sources */, AE48658C1B067954005DB302 /* CDRColorizedReporter.m in Sources */, 3492DAA41BA6F9E70032B35A /* CDRSpecRun.m in Sources */, AE48658D1B067954005DB302 /* CDRDefaultReporter.m in Sources */, AE48658E1B067954005DB302 /* CDRJUnitXMLReporter.m in Sources */, AE48658F1B067954005DB302 /* CDROTestReporter.m in Sources */, AE4865901B067954005DB302 /* CDRReportDispatcher.m in Sources */, AE4865911B067954005DB302 /* CDRTeamCityReporter.m in Sources */, AE4865921B067954005DB302 /* CDRBufferedDefaultReporter.m in Sources */, AE4865931B067954005DB302 /* CDRExample.m in Sources */, AE4865941B067954005DB302 /* CDRExampleBase.m in Sources */, AE4865951B067954005DB302 /* CDRExampleGroup.m in Sources */, AE4865961B067954005DB302 /* CDRFunctions.m in Sources */, AE4865971B067954005DB302 /* CDRTestBundleRunner.m in Sources */, AE4865981B067954005DB302 /* CDRRuntimeUtilities.m in Sources */, AE4865991B067954005DB302 /* CDRSharedExampleGroupPool.m in Sources */, F7C9BC031D45E19A00B694C0 /* CDRRunState.m in Sources */, AE48659A1B067954005DB302 /* CDRSpec.m in Sources */, AE48659B1B067954005DB302 /* CDRSpecFailure.m in Sources */, AE48659C1B067954005DB302 /* CDRSpecHelper.m in Sources */, AE48659D1B067954005DB302 /* CDRSymbolicator.m in Sources */, AE48659E1B067954005DB302 /* CDRTypeUtilities.m in Sources */, AE48659F1B067954005DB302 /* CDRNil.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE1FB311DC271300029872 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AE4A946118807DA6008566F5 /* RejectedMethod.mm in Sources */, F7C9BBF71D3E860000B694C0 /* CDRStateTracker.m in Sources */, AEEE1FF311DC27B800029872 /* CDRDefaultReporter.m in Sources */, 34ADD2E01921F18100B057AC /* AnyInstanceOfClassArgument.mm in Sources */, AE31A2A119C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */, AEEE1FF411DC27B800029872 /* CDRExample.m in Sources */, 34F3DF7F1A6ABA2E003041DA /* CDRNil.m in Sources */, AEEE1FF511DC27B800029872 /* CDRExampleBase.m in Sources */, 3492DA971BA670C10032B35A /* CDRXCTestFunctions.m in Sources */, 3492DAA21BA6F9E70032B35A /* CDRSpecRun.m in Sources */, AEEE1FF611DC27B800029872 /* CDRExampleGroup.m in Sources */, AEEE1FF711DC27B800029872 /* CDRFunctions.m in Sources */, AEEE1FF811DC27B800029872 /* CDRSpec.m in Sources */, F7F4099B1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */, AEEE201111DC27B800029872 /* CDRSpecHelper.m in Sources */, 1FF449B118A0C03800AF94B0 /* CDRBufferedDefaultReporter.m in Sources */, AEFD17BB11DD1E9E00F4448A /* CDRSharedExampleGroupPool.m in Sources */, AEC9DEEE12C2CC7E0039512D /* CDRColorizedReporter.m in Sources */, 4206446A139B44F600C85605 /* CDRTeamCityReporter.m in Sources */, 96EA1CA8142C6425001A78E0 /* CDROTestReporter.m in Sources */, AE0C9D8E19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m in Sources */, 34681C2C18FE451E009D38AC /* CDRTypeUtilities.m in Sources */, 96EA1CAA142C6425001A78E0 /* CDRTestBundleRunner.m in Sources */, 492951E01481AAFA00FA8916 /* CDRJUnitXMLReporter.m in Sources */, 6628FC9C14C4DEC50016652A /* CDRSpy.mm in Sources */, 34ADE41818F23C8E00BD1E99 /* NSMethodSignature+Cedar.m in Sources */, 1FF4497D18A0B37A00AF94B0 /* AnyArgument.mm in Sources */, AE4E9B9419C8B44700D794CE /* NSInvocation+CDRXExample.m in Sources */, AEEF360719DE21DB00794484 /* CDRSpecFailure.m in Sources */, AE9AA68715AB7E0900617E1A /* CDRClassFake.mm in Sources */, AE9AA6DE15AE0BE200617E1A /* CedarDoubleImpl.mm in Sources */, 1FE15C1D1869091900207F0C /* CDRReportDispatcher.m in Sources */, AE167EF215B216DA005960B9 /* RaiseException.mm in Sources */, 34ADD2E71921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm in Sources */, AE74906F15B48690008EA127 /* CDRProtocolFake.mm in Sources */, AE34724D19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */, 1F483E33187D39D000521F81 /* CDROTestNamer.m in Sources */, AE74907115B486CD008EA127 /* CDRFake.mm in Sources */, AE36AC6515B5CA6E00EB6C51 /* CedarDouble.mm in Sources */, AEB1A74215F304A9002E4167 /* StubbedMethod.mm in Sources */, AE94D04515F3449500A0C2B7 /* AnyInstanceArgument.mm in Sources */, AE55BF1B19A7CF58005948E6 /* CDRRuntimeUtilities.m in Sources */, AEC7873915F440980058A27B /* InvocationMatcher.mm in Sources */, AEC7874D15F444A50058A27B /* HaveReceived.mm in Sources */, 969B6F84160C61E000C7C792 /* CDRSymbolicator.m in Sources */, E31179D5161FD937007D3CDE /* CDRSlowTestStatistics.m in Sources */, AE7F1708172730B000E1146D /* NSInvocation+Cedar.m in Sources */, AE02021917452007009A7915 /* StringifiersBase.mm in Sources */, AEE8DBD7175FFCF3008AF18A /* CDRSpyInfo.mm in Sources */, CA17999017F89C9700C38060 /* RespondTo.mm in Sources */, 5898ACDB8101DA643EDCCD5B /* ConformTo.mm in Sources */, F7C9BC021D45E16200B694C0 /* CDRRunState.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE218311DC28E200029872 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AEEE21C411DC290400029872 /* SpecSpec2.m in Sources */, 346F646E1B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */, 34DB67491C2B4D6A00206663 /* SwiftSpec.swift in Sources */, F7C8F3041BC63A000088069D /* ContainSubsetSpec.mm in Sources */, AEEE21BF11DC290400029872 /* CDRExampleSpec.mm in Sources */, AEEE21BE11DC290400029872 /* CDRExampleGroupSpec.mm in Sources */, AEEE21C111DC290400029872 /* main.mm in Sources */, AEEE21C211DC290400029872 /* CDRHooksSpec.mm in Sources */, AEEE21C311DC290400029872 /* SpecSpec.mm in Sources */, AE8C87AE136245BB006C9305 /* ExpectFailureWithMessage.mm in Sources */, 96EA1CBA142C6560001A78E0 /* CDRSpecFailureSpec.mm in Sources */, AEF7301B13ECC4AE00786282 /* BeCloseToSpec.mm in Sources */, 34681C3018FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm in Sources */, AE53B68417E7CD8D00D83D5E /* ObjectWithWeakDelegate.m in Sources */, AE0F354B19E7073B00B9F116 /* OSXGeometryEqualSpecSpec.mm in Sources */, F71C2F341D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */, AE80788D183C71950078C608 /* ArgumentReleaser.m in Sources */, AE4A945B187F7E52008566F5 /* BeFalsySpec.mm in Sources */, AEF7301D13ECC4AE00786282 /* BeInstanceOfSpec.mm in Sources */, AE807890183C71950078C608 /* SimpleIncrementer.m in Sources */, AEF7301F13ECC4AE00786282 /* BeNilSpec.mm in Sources */, AEF7302113ECC4AE00786282 /* BeSameInstanceAsSpec.mm in Sources */, AE06D88017AEEE230084D27C /* ObjectWithForwardingTarget.m in Sources */, AEF7302313ECC4AE00786282 /* BeTruthySpec.mm in Sources */, AEF7302513ECC4AE00786282 /* EqualSpec.mm in Sources */, 346D1AAB1BBC43E600BECD4B /* CDROTestReporterSpec.mm in Sources */, AED10EBC18F46C0E00950904 /* FooSuperclass.m in Sources */, AEF7302713ECC4AE00786282 /* MutableEqualSpec.mm in Sources */, AEF7302C13ECC4E700786282 /* BeEmptySpec.mm in Sources */, 1F882AAA180F9B6300533238 /* BeNil_ARCSpec.mm in Sources */, AE18A80A13F4640600C8872C /* ContainSpec.mm in Sources */, AE6F3F341458D7C100C98F1E /* BeGreaterThanSpec.mm in Sources */, AEF33009145B4E3B002F93BB /* BeGTESpec.mm in Sources */, 34F3DF821A6ABB21003041DA /* CDRNilSpec.mm in Sources */, AEF3301C145B62E9002F93BB /* BeLessThanSpec.mm in Sources */, AEF3301E145B68D7002F93BB /* BeLTESpec.mm in Sources */, 966E74ED145A6CA0002E8D49 /* ShouldSyntaxSpec.mm in Sources */, AEBB92611496C1F000EEBD59 /* RaiseExceptionSpec.mm in Sources */, 492951E41482FF6300FA8916 /* CDRJUnitXMLReporterSpec.mm in Sources */, 66F00B5214C4D97C00146D88 /* CDRSpySpec.mm in Sources */, E4BCFDD21817FA110083ED98 /* ObjectWithProperty.m in Sources */, 6639A77F14C50D0100B564B7 /* HaveReceivedSpec.mm in Sources */, AE9AA68015AB748E00617E1A /* CDRClassFakeSpec.mm in Sources */, AE807893183C71950078C608 /* SimpleKeyValueObserver.m in Sources */, AE9AA69715ADB99800617E1A /* CedarDoubleSharedExamples.mm in Sources */, F7C9BBED1D3E83E500B694C0 /* CDRSpecRunSpec.mm in Sources */, AE3E8F39184FEEE900633740 /* ObjectWithCollections.m in Sources */, AE74903215B45EBA008EA127 /* CDRProtocolFakeSpec.mm in Sources */, 343FAFEA190FDAEC0085AFEC /* DeallocNotifier.m in Sources */, 96C95B7E161339160018606B /* CDRSymbolicatorSpec.mm in Sources */, 1F882AAC180FA8D800533238 /* BeSameInstanceAs_ARCSpec.mm in Sources */, 9672F0A91615C3F40012ED58 /* CDRSpecSpec.mm in Sources */, 9D28051918E2321D00887CC4 /* ObjectWithValueEquality.m in Sources */, E32861321604F287001FA77E /* FibonacciCalculator.m in Sources */, 96B5918F1630F5840068EA5E /* ObjCHeadersSpec.mm in Sources */, AE0BF06F1B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */, AEE0665617315C20003CA143 /* CedarNiceFakeSharedExamples.mm in Sources */, AEE0665917315DB8003CA143 /* CedarOrdinaryFakeSharedExamples.mm in Sources */, AE9EAAD9178C789800CCF7DA /* CDRDefaultReporterSpec.mm in Sources */, AE0721E0187513870031CC42 /* ExistSpec.mm in Sources */, AE0695F317A1885A0053E59A /* CedarDoubleARCSharedExamples.mm in Sources */, 5898A7EC5992B2CC74E399F6 /* RespondToSpec.mm in Sources */, 5898A61AAABFE1802E87E6C3 /* ConformToSpec.mm in Sources */, 4523F335DBD90BD048BB7397 /* GDataXMLNode.m in Sources */, 4523F7CCCA3C9010878941F7 /* ExampleWithPublicRunDates.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE222611DC2B0600029872 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AEEE223111DC2B6500029872 /* CDRDefaultReporter.m in Sources */, AE34724E19C37ECF005CA6F1 /* CDRXCTestCase.m in Sources */, AE0C9D8F19C0C64200B4DD2B /* CDRSpec+XCTestSupport.m in Sources */, AEEE223211DC2B6500029872 /* CDRExample.m in Sources */, AEEE223311DC2B6500029872 /* CDRExampleBase.m in Sources */, F7C9BBF61D3E85FF00B694C0 /* CDRStateTracker.m in Sources */, AEEE223411DC2B6500029872 /* CDRExampleGroup.m in Sources */, AEEF360819DE21ED00794484 /* CDRSpecFailure.m in Sources */, AEEE223511DC2B6500029872 /* CDRFunctions.m in Sources */, AEEE223611DC2B6500029872 /* CDRSpec.m in Sources */, AEEE223711DC2B6500029872 /* CDRSpecHelper.m in Sources */, 34F3DF801A6ABA2E003041DA /* CDRNil.m in Sources */, AEEE223D11DC2B6D00029872 /* CedarApplicationDelegate.m in Sources */, AE55BF1C19A7CF58005948E6 /* CDRRuntimeUtilities.m in Sources */, 1FF4497E18A0B37A00AF94B0 /* AnyArgument.mm in Sources */, AE4E9B9519C8B44700D794CE /* NSInvocation+CDRXExample.m in Sources */, AE9855AE1236E7080024094E /* CDRSharedExampleGroupPool.m in Sources */, F7F4099C1B2E3C8B001EFA14 /* CDRXCTestObserver.m in Sources */, AEC9DEF412C2CC8F0039512D /* CDRColorizedReporter.m in Sources */, 1F483E34187D3CD200521F81 /* CDROTestNamer.m in Sources */, 4206446B139B44F600C85605 /* CDRTeamCityReporter.m in Sources */, 96EA1CA9142C6425001A78E0 /* CDROTestReporter.m in Sources */, 3492DA981BA670C10032B35A /* CDRXCTestFunctions.m in Sources */, 34681C2E18FE4884009D38AC /* CDRTypeUtilities.m in Sources */, 1FE15C201869091900207F0C /* CDRReportDispatcher.m in Sources */, 960118BC1434867E00825FFF /* NSBundle+MainBundleHijack.m in Sources */, 492951E11481AAFA00FA8916 /* CDRJUnitXMLReporter.m in Sources */, 6639A78714C540CC00B564B7 /* CDRSpy.mm in Sources */, AE9AA68615AB7A8700617E1A /* CDRClassFake.mm in Sources */, AE9AA6DF15AE0BE200617E1A /* CedarDoubleImpl.mm in Sources */, AE167EF315B216DA005960B9 /* RaiseException.mm in Sources */, 34ADD2E81921F33800B057AC /* AnyInstanceConformingToProtocolArgument.mm in Sources */, AE74907215B486CD008EA127 /* CDRFake.mm in Sources */, 3492DAA31BA6F9E70032B35A /* CDRSpecRun.m in Sources */, AE74907715B493C4008EA127 /* CDRProtocolFake.mm in Sources */, AE36AC6615B5CA6E00EB6C51 /* CedarDouble.mm in Sources */, 34ADE41918F23E6B00BD1E99 /* NSMethodSignature+Cedar.m in Sources */, AEB1A74315F304A9002E4167 /* StubbedMethod.mm in Sources */, AE94D04615F3449500A0C2B7 /* AnyInstanceArgument.mm in Sources */, 1FF449B218A0C03900AF94B0 /* CDRBufferedDefaultReporter.m in Sources */, AE4A946218807DA6008566F5 /* RejectedMethod.mm in Sources */, AE31A2A219C0F23F00C438C1 /* CDRXCTestSuite.m in Sources */, AEC7873A15F440980058A27B /* InvocationMatcher.mm in Sources */, AEC7874E15F444A50058A27B /* HaveReceived.mm in Sources */, 969B6F86160C678400C7C792 /* CDRSymbolicator.m in Sources */, E31179D6161FD937007D3CDE /* CDRSlowTestStatistics.m in Sources */, AE7F170B172730B000E1146D /* NSInvocation+Cedar.m in Sources */, F7C9BC061D45E19C00B694C0 /* CDRRunState.m in Sources */, AEA8962C19D0C242007D5C08 /* CDRTestBundleRunner.m in Sources */, 34ADD2E11921F18100B057AC /* AnyInstanceOfClassArgument.mm in Sources */, AE02021A17452007009A7915 /* StringifiersBase.mm in Sources */, AEE8DBD8175FFCF3008AF18A /* CDRSpyInfo.mm in Sources */, CA17999117F89C9700C38060 /* RespondTo.mm in Sources */, 5898AF335BC09A1CD5B011C6 /* ConformTo.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; AEEE227311DC2CF900029872 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( AEEE228011DC2D5200029872 /* CDRExampleSpec.mm in Sources */, AEEE228311DC2D5200029872 /* CDRHooksSpec.mm in Sources */, AEEE228411DC2D5200029872 /* SpecSpec.mm in Sources */, 1FDCD5601821D3BB00B511DB /* BeNil_ARCSpec.mm in Sources */, AEEE228511DC2D5200029872 /* SpecSpec2.m in Sources */, E4BCFDD31817FA110083ED98 /* ObjectWithProperty.m in Sources */, AEEE228711DC2D5800029872 /* main.mm in Sources */, AE807895183C71950078C608 /* SimpleKeyValueObserver.m in Sources */, 1F47B9A8186D69CD005A8CE1 /* CDROTestReporterSpec.mm in Sources */, AE53B68117E7BCD300D83D5E /* CedarOrdinaryFakeSharedExamples.mm in Sources */, 34D4B5C318F3AE0400FB2C3B /* UIKitContainSpec.mm in Sources */, F7C8F3071BC63A000088069D /* ContainSubsetSpec.mm in Sources */, 9D28051A18E2324200887CC4 /* ObjectWithValueEquality.m in Sources */, AE8C87AF136245BD006C9305 /* ExpectFailureWithMessage.mm in Sources */, 96EA1CBB142C6560001A78E0 /* CDRSpecFailureSpec.mm in Sources */, AEF7301C13ECC4AE00786282 /* BeCloseToSpec.mm in Sources */, AEF7301E13ECC4AE00786282 /* BeInstanceOfSpec.mm in Sources */, AE807892183C71950078C608 /* SimpleIncrementer.m in Sources */, AEF7302013ECC4AE00786282 /* BeNilSpec.mm in Sources */, AEF7302213ECC4AE00786282 /* BeSameInstanceAsSpec.mm in Sources */, AE0BF0701B8E10D8000B0EE7 /* BlockMatcher_ARCSpecSpec.mm in Sources */, AE0721E1187513870031CC42 /* ExistSpec.mm in Sources */, AEF7302413ECC4AE00786282 /* BeTruthySpec.mm in Sources */, AE53B67E17E7BCAA00D83D5E /* CDRClassFakeSpec.mm in Sources */, AEF7302613ECC4AE00786282 /* EqualSpec.mm in Sources */, AEF7302813ECC4AE00786282 /* MutableEqualSpec.mm in Sources */, 1FDCD5611821D3BF00B511DB /* BeSameInstanceAs_ARCSpec.mm in Sources */, AEF7302D13ECC4E700786282 /* BeEmptySpec.mm in Sources */, 228F3FA717E3ECD10000C8AF /* CDRSpyiOSSpec.mm in Sources */, 44B9A71F1888661100CBCA1B /* ExampleWithPublicRunDates.mm in Sources */, 34F3DF831A6ABB21003041DA /* CDRNilSpec.mm in Sources */, AE18A80B13F4640600C8872C /* ContainSpec.mm in Sources */, AED10EBD18F46C0E00950904 /* FooSuperclass.m in Sources */, 343FAFEB190FDAEC0085AFEC /* DeallocNotifier.m in Sources */, AE6F3F351458D7C100C98F1E /* BeGreaterThanSpec.mm in Sources */, 34681C3118FE4B68009D38AC /* CDRTypeUtilitiesSpec.mm in Sources */, AE53B68217E7BCE700D83D5E /* CedarNiceFakeSharedExamples.mm in Sources */, AEF3300A145B4E3B002F93BB /* BeGTESpec.mm in Sources */, F7C9BBEF1D3E83EB00B694C0 /* CDRSpecRunSpec.mm in Sources */, AEF33015145B6188002F93BB /* BeLessThanSpec.mm in Sources */, AEF3301F145B68D7002F93BB /* BeLTESpec.mm in Sources */, 966E74EE145A6CA0002E8D49 /* ShouldSyntaxSpec.mm in Sources */, 44B9A71E1888660400CBCA1B /* GDataXMLNode.m in Sources */, AEBB92631496C1F000EEBD59 /* RaiseExceptionSpec.mm in Sources */, AE4A945C187F7E52008566F5 /* BeFalsySpec.mm in Sources */, AE02E82A184EF2A300414F19 /* CDRExampleGroupSpec.mm in Sources */, 492951E51482FF6300FA8916 /* CDRJUnitXMLReporterSpec.mm in Sources */, AE53B68017E7BCAA00D83D5E /* CDRSpySpec.mm in Sources */, AE9AA69815ADB99800617E1A /* CedarDoubleSharedExamples.mm in Sources */, AE3E8F3A184FEEEB00633740 /* ObjectWithCollections.m in Sources */, AE53B68317E7BDA900D83D5E /* HaveReceivedSpec.mm in Sources */, AE06D88117AEEE230084D27C /* ObjectWithForwardingTarget.m in Sources */, 9672F0A71615C1C10012ED58 /* CDRSymbolicatorSpec.mm in Sources */, 9672F0AA1615C3F40012ED58 /* CDRSpecSpec.mm in Sources */, 346F646F1B82D3C900F64156 /* BlockMatcherSpec.mm in Sources */, E32861331604F287001FA77E /* FibonacciCalculator.m in Sources */, F71C2F371D3DAD71003B37DC /* CedarTestSpecBuilder.m in Sources */, 96B591911630F5B10068EA5E /* ObjCHeadersSpec.mm in Sources */, AE80788F183C71950078C608 /* ArgumentReleaser.m in Sources */, AE7DD11217296CB20058EB3B /* CedarApplicationDelegateSpec.mm in Sources */, AEC40C54174AC51D00474D2D /* UIKitEqualSpec.mm in Sources */, AE5218D3175979CA00A656BC /* ObjectWithWeakDelegate.m in Sources */, AE5218D5175979D900A656BC /* WeakReferenceCompatibilitySpec.mm in Sources */, AE71E7CC175E958F002A54D5 /* ARCViewController.m in Sources */, AE9EAADA178C789900CCF7DA /* CDRDefaultReporterSpec.mm in Sources */, AE0695F417A1885A0053E59A /* CedarDoubleARCSharedExamples.mm in Sources */, AE53B67F17E7BCAA00D83D5E /* CDRProtocolFakeSpec.mm in Sources */, 5898AC04D63A7FAFFA2A4D5C /* RespondToSpec.mm in Sources */, 5898A49E3306FFF7A99AC150 /* ConformToSpec.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 1F45A3CB180E4796003C1E36 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 96B5F9F5144A81A7000A6A5D /* Cedar-iOS HostApp */; targetProxy = 1F45A3CC180E4796003C1E36 /* PBXContainerItemProxy */; }; 346262871B99C1DC002CAEBD /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 346262831B99C1DC002CAEBD /* Cedar-watchOS Specs Extension */; targetProxy = 346262861B99C1DC002CAEBD /* PBXContainerItemProxy */; }; 3462629E1B99D0BB002CAEBD /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 346261DE1B995239002CAEBD /* Cedar-watchOS */; targetProxy = 3462629D1B99D0BB002CAEBD /* PBXContainerItemProxy */; }; 346D1AA71BBC406000BECD4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE222811DC2B0600029872 /* Cedar-iOS StaticLib */; targetProxy = 346D1AA61BBC406000BECD4B /* PBXContainerItemProxy */; }; 34852D241BBE36B90072D249 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 346262771B99C1DB002CAEBD /* Cedar-watchOS Specs */; targetProxy = 34852D231BBE36B90072D249 /* PBXContainerItemProxy */; }; 34D7C4721BB9B72300E8E523 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 34D7C3C91BB9747400E8E523 /* Cedar-tvOS */; targetProxy = 34D7C4711BB9B72300E8E523 /* PBXContainerItemProxy */; }; 96A07EEF13F276640021974D /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE1FB511DC271300029872 /* Cedar-OSX */; targetProxy = 96A07EF013F276640021974D /* PBXContainerItemProxy */; }; AE02E80F184EADE100414F19 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE224B11DC2BBB00029872 /* Cedar-iOS StaticFramework */; targetProxy = AE02E80E184EADE100414F19 /* PBXContainerItemProxy */; }; AE03FC111B06C39500013784 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AE4864F71B067620005DB302 /* Cedar-iOS */; targetProxy = AE03FC101B06C39500013784 /* PBXContainerItemProxy */; }; AE248FAC19DCD52500092C14 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AE248F9719DCD52500092C14 /* Cedar-OSX HostApp */; targetProxy = AE248FAB19DCD52500092C14 /* PBXContainerItemProxy */; }; AE248FC019DCD5E200092C14 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE1FB511DC271300029872 /* Cedar-OSX */; targetProxy = AE248FBF19DCD5E200092C14 /* PBXContainerItemProxy */; }; AE4865A31B067F53005DB302 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE222811DC2B0600029872 /* Cedar-iOS StaticLib */; targetProxy = AE4865A21B067F53005DB302 /* PBXContainerItemProxy */; }; AEEE218B11DC28E700029872 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = AEEE1FB511DC271300029872 /* Cedar-OSX */; targetProxy = AEEE218A11DC28E700029872 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 96D3447F144A82D100352C4A /* DummyView.xib */ = { isa = PBXVariantGroup; children = ( 96D34480144A82D100352C4A /* en */, ); name = DummyView.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1F45A3DB180E4796003C1E36 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_LIBRARY_DIR)/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); HEADER_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"/Source/Matchers/UIKit", ); INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", ); OTHER_LDFLAGS = ( "-lstdc++", "-ObjC", "-framework", XCTest, ); PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cedar-iOS HostApp.app/Cedar-iOS HostApp"; WRAPPER_EXTENSION = xctest; }; name = Debug; }; 1F45A3DC180E4796003C1E36 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_LIBRARY_DIR)/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"/Source/Matchers/UIKit", ); INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", ); OTHER_LDFLAGS = ( "-lstdc++", "-ObjC", "-framework", XCTest, ); PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cedar-iOS HostApp.app/Cedar-iOS HostApp"; WRAPPER_EXTENSION = xctest; }; name = Release; }; 346261E41B99523A002CAEBD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; 346261E51B99523A002CAEBD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; 346262961B99C1DC002CAEBD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; DEBUG_INFORMATION_FORMAT = dwarf; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, ); INFOPLIST_FILE = "Spec/watchOS/Extension-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.Cedar-watchOS-HostApp.watchkitapp.watchkitextension"; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; 346262971B99C1DC002CAEBD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, ); INFOPLIST_FILE = "Spec/watchOS/Extension-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.Cedar-watchOS-HostApp.watchkitapp.watchkitextension"; PRODUCT_NAME = "${TARGET_NAME}"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = 4; VALIDATE_PRODUCT = YES; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; 3462629A1B99C1DC002CAEBD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; DEBUG_INFORMATION_FORMAT = dwarf; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = Cedar_watchOS_Specs_Extension; INFOPLIST_FILE = "Spec/watchOS/App-Info.plist"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.Cedar-watchOS-HostApp.watchkitapp"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Debug; }; 3462629B1B99C1DC002CAEBD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; IBSC_MODULE = Cedar_watchOS_Specs_Extension; INFOPLIST_FILE = "Spec/watchOS/App-Info.plist"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.Cedar-watchOS-HostApp.watchkitapp"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 4; VALIDATE_PRODUCT = YES; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; name = Release; }; 34852D1F1BBE35FF0072D249 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = Spec/iOS/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; WRAPPER_EXTENSION = app; }; name = Debug; }; 34852D201BBE35FF0072D249 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = Spec/iOS/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; name = Release; }; 34D7C3CF1BB9747400E8E523 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_DYNAMIC_NO_PIC = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_NO_COMMON_BLOCKS = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = appletvos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 34D7C3D01BB9747400E8E523 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_NO_COMMON_BLOCKS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = appletvos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 34D7C46F1BB9B71600E8E523 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_TESTABILITY = 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_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, ); INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TVOS_DEPLOYMENT_TARGET = 9.0; WRAPPER_EXTENSION = xctest; }; name = Debug; }; 34D7C4701BB9B71600E8E523 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /usr/include/libxml2, ); INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = xctest; }; name = Release; }; 96A07F0613F276640021974D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INSTALL_PATH = /usr/local/bin; MACOSX_DEPLOYMENT_TARGET = ""; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-framework", Foundation, ); PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 96A07F0713F276640021974D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", ); GCC_MODEL_TUNING = G5; INSTALL_PATH = /usr/local/bin; MACOSX_DEPLOYMENT_TARGET = ""; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-framework", Foundation, ); PRODUCT_NAME = "$(TARGET_NAME)"; ZERO_LINK = NO; }; name = Release; }; 96B5FA23144A81A8000A6A5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = DEBUG; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = Spec/iOS/Info.plist; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; WRAPPER_EXTENSION = app; }; name = Debug; }; 96B5FA24144A81A8000A6A5D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = NO; INFOPLIST_FILE = Spec/iOS/Info.plist; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; name = Release; }; AE02E809184EABCE00414F19 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; FRAMEWORK_SEARCH_PATHS = ( "\"$(BUILD_DIR)\"/$(CONFIGURATION)-iphoneuniversal/**", "$(inherited)", ); GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = Spec/iOS/Info.plist; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", "Cedar-iOS", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; REEXPORTED_FRAMEWORK_NAMES = ""; SDKROOT = iphoneos; WRAPPER_EXTENSION = app; }; name = Debug; }; AE02E80A184EABCE00414F19 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "\"$(BUILD_DIR)\"/$(CONFIGURATION)-iphoneuniversal/**", "$(inherited)", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = Spec/iOS/Info.plist; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", "Cedar-iOS", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; REEXPORTED_FRAMEWORK_NAMES = ""; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; WRAPPER_EXTENSION = app; }; name = Release; }; AE03FC091B06C33B00013784 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; CLANG_ENABLE_MODULES = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 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_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /usr/include/libxml2, ); INFOPLIST_FILE = Spec/iOS/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", Foundation, "-framework", UIKit, "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; AE03FC0A1B06C33B00013784 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = NO; CLANG_ENABLE_MODULES = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /usr/include/libxml2, ); INFOPLIST_FILE = Spec/iOS/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", Foundation, "-framework", UIKit, "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; AE248FB319DCD52500092C14 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = 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_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Spec/SpecBundle/OS X Host App/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; name = Debug; }; AE248FB419DCD52500092C14 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Spec/SpecBundle/OS X Host App/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; }; name = Release; }; AE248FB619DCD52500092C14 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COMBINE_HIDPI_IMAGES = YES; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", ); 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_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cedar-OSX HostApp.app/Contents/MacOS/Cedar-OSX HostApp"; WRAPPER_EXTENSION = xctest; }; name = Debug; }; AE248FB719DCD52500092C14 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", "$(inherited)", ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Spec/SpecBundle/SpecBundle-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.pivotallabs.cedar.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cedar-OSX HostApp.app/Contents/MacOS/Cedar-OSX HostApp"; WRAPPER_EXTENSION = xctest; }; name = Release; }; AE48650B1B067621005DB302 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_DYNAMIC_NO_PIC = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_NO_COMMON_BLOCKS = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = ""; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = NO; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; AE48650C1B067621005DB302 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = NO; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = YES; GCC_C_LANGUAGE_STANDARD = "compiler-default"; GCC_INLINES_ARE_PRIVATE_EXTERN = NO; GCC_NO_COMMON_BLOCKS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; AEEE1FA711DC26EA00029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = "-DDEVELOPER_BIN_DIR=@\\\"${DEVELOPER_BIN_DIR}\\\""; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-fobjc-call-cxx-cdtors", ); SWIFT_VERSION = 3.0; WARNING_CFLAGS = "-Wno-idiomatic-parentheses"; }; name = Debug; }; AEEE1FA811DC26EA00029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_MISSING_NEWLINE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_CFLAGS = "-DDEVELOPER_BIN_DIR=@\\\"${DEVELOPER_BIN_DIR}\\\""; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-fobjc-call-cxx-cdtors", ); SWIFT_VERSION = 3.0; WARNING_CFLAGS = "-Wno-idiomatic-parentheses"; }; name = Release; }; AEEE1FBA11DC271300029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); FRAMEWORK_VERSION = A; GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Frameworks"; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ( "-framework", Foundation, ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; }; name = Debug; }; AEEE1FBB11DC271300029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); FRAMEWORK_VERSION = A; GCC_MODEL_TUNING = G5; INFOPLIST_FILE = "Cedar-Info.plist"; INSTALL_PATH = "$(HOME)/Library/Frameworks"; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = ( "-framework", Foundation, ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = Cedar; ZERO_LINK = NO; }; name = Release; }; AEEE218811DC28E200029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", ); GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /usr/include/libxml2, ); INSTALL_PATH = /usr/local/bin; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-framework", Foundation, "-lxml2", ); PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; AEEE218911DC28E200029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ENABLE_MODULES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"", ); GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, /usr/include/libxml2, ); INSTALL_PATH = /usr/local/bin; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.9; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-framework", Foundation, "-lxml2", ); PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Spec/Swift/Spec-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; ZERO_LINK = NO; }; name = Release; }; AEEE222A11DC2B0600029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; PRODUCT_NAME = Cedar; SDKROOT = iphoneos; }; name = Debug; }; AEEE222B11DC2B0600029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); PRODUCT_NAME = Cedar; SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; }; AEEE224C11DC2BBB00029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "Cedar-iOS"; SDKROOT = iphoneos; }; name = Debug; }; AEEE224D11DC2BBB00029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; PRODUCT_NAME = "Cedar-iOS"; SDKROOT = iphoneos; ZERO_LINK = NO; }; name = Release; }; AEEE227911DC2CF900029872 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", "\"$(SRCROOT)/Spec/Support\"", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"/Source/Headers/Matchers/UIKit", /usr/include/libxml2, ); INFOPLIST_FILE = Spec/iOS/Info.plist; INSTALL_PATH = "$(HOME)/Applications"; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", Foundation, "-framework", UIKit, "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; VERSION_INFO_FILE = $TARGET_NAME; }; name = Debug; }; AEEE227A11DC2CF900029872 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SRCROOT)", "\"$(SRCROOT)/Spec/Support\"", "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = NO; HEADER_SEARCH_PATHS = ( "$(inherited)", "\"$(SRCROOT)\"/Source/Headers/Matchers/UIKit", /usr/include/libxml2, ); INFOPLIST_FILE = Spec/iOS/Info.plist; INSTALL_PATH = "$(HOME)/Applications"; OTHER_LDFLAGS = ( "-lstdc++", "-all_load", "-ObjC", "-framework", Foundation, "-framework", UIKit, "-lxml2", ); PRODUCT_BUNDLE_IDENTIFIER = "io.pivotal.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; VERSION_INFO_FILE = $TARGET_NAME; ZERO_LINK = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1F45A3DA180E4796003C1E36 /* Build configuration list for PBXNativeTarget "Cedar-iOS SpecBundle" */ = { isa = XCConfigurationList; buildConfigurations = ( 1F45A3DB180E4796003C1E36 /* Debug */, 1F45A3DC180E4796003C1E36 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 346261E61B99523A002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 346261E41B99523A002CAEBD /* Debug */, 346261E51B99523A002CAEBD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 346262951B99C1DC002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS Specs Extension" */ = { isa = XCConfigurationList; buildConfigurations = ( 346262961B99C1DC002CAEBD /* Debug */, 346262971B99C1DC002CAEBD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 346262991B99C1DC002CAEBD /* Build configuration list for PBXNativeTarget "Cedar-watchOS Specs" */ = { isa = XCConfigurationList; buildConfigurations = ( 3462629A1B99C1DC002CAEBD /* Debug */, 3462629B1B99C1DC002CAEBD /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 34852D1E1BBE35FF0072D249 /* Build configuration list for PBXNativeTarget "Cedar-watchOS HostApp" */ = { isa = XCConfigurationList; buildConfigurations = ( 34852D1F1BBE35FF0072D249 /* Debug */, 34852D201BBE35FF0072D249 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 34D7C3D11BB9747400E8E523 /* Build configuration list for PBXNativeTarget "Cedar-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( 34D7C3CF1BB9747400E8E523 /* Debug */, 34D7C3D01BB9747400E8E523 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 34D7C46E1BB9B71600E8E523 /* Build configuration list for PBXNativeTarget "Cedar-tvOS SpecBundle" */ = { isa = XCConfigurationList; buildConfigurations = ( 34D7C46F1BB9B71600E8E523 /* Debug */, 34D7C4701BB9B71600E8E523 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 96A07F0513F276640021974D /* Build configuration list for PBXNativeTarget "Cedar-OSX FocusedSpecs" */ = { isa = XCConfigurationList; buildConfigurations = ( 96A07F0613F276640021974D /* Debug */, 96A07F0713F276640021974D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 96B5FA22144A81A8000A6A5D /* Build configuration list for PBXNativeTarget "Cedar-iOS HostApp" */ = { isa = XCConfigurationList; buildConfigurations = ( 96B5FA23144A81A8000A6A5D /* Debug */, 96B5FA24144A81A8000A6A5D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AE02E808184EABCE00414F19 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticFrameworkSpecs" */ = { isa = XCConfigurationList; buildConfigurations = ( AE02E809184EABCE00414F19 /* Debug */, AE02E80A184EABCE00414F19 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AE03FC0D1B06C33B00013784 /* Build configuration list for PBXNativeTarget "Cedar-iOS Specs" */ = { isa = XCConfigurationList; buildConfigurations = ( AE03FC091B06C33B00013784 /* Debug */, AE03FC0A1B06C33B00013784 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AE248FB219DCD52500092C14 /* Build configuration list for PBXNativeTarget "Cedar-OSX HostApp" */ = { isa = XCConfigurationList; buildConfigurations = ( AE248FB319DCD52500092C14 /* Debug */, AE248FB419DCD52500092C14 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AE248FB519DCD52500092C14 /* Build configuration list for PBXNativeTarget "Cedar-OSX SpecBundle" */ = { isa = XCConfigurationList; buildConfigurations = ( AE248FB619DCD52500092C14 /* Debug */, AE248FB719DCD52500092C14 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AE48650F1B067621005DB302 /* Build configuration list for PBXNativeTarget "Cedar-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( AE48650B1B067621005DB302 /* Debug */, AE48650C1B067621005DB302 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE1FA911DC26EA00029872 /* Build configuration list for PBXProject "Cedar" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE1FA711DC26EA00029872 /* Debug */, AEEE1FA811DC26EA00029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE1FBC11DC271300029872 /* Build configuration list for PBXNativeTarget "Cedar-OSX" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE1FBA11DC271300029872 /* Debug */, AEEE1FBB11DC271300029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE21CA11DC292600029872 /* Build configuration list for PBXNativeTarget "Cedar-OSX Specs" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE218811DC28E200029872 /* Debug */, AEEE218911DC28E200029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE223011DC2B1300029872 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticLib" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE222A11DC2B0600029872 /* Debug */, AEEE222B11DC2B0600029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE225311DC2BC000029872 /* Build configuration list for PBXAggregateTarget "Cedar-iOS StaticFramework" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE224C11DC2BBB00029872 /* Debug */, AEEE224D11DC2BBB00029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; AEEE227B11DC2CF900029872 /* Build configuration list for PBXNativeTarget "Cedar-iOS StaticLib Specs" */ = { isa = XCConfigurationList; buildConfigurations = ( AEEE227911DC2CF900029872 /* Debug */, AEEE227A11DC2CF900029872 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = AEEE1FA611DC26EA00029872 /* Project object */; } ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-OSX SpecBundle.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-OSX Specs.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-OSX.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-iOS SpecBundle.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-iOS StaticFramework.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-iOS StaticLib.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-iOS.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-tvOS SpecBundle.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-tvOS.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-watchOS Specs.xcscheme ================================================ ================================================ FILE: Cedar.xcodeproj/xcshareddata/xcschemes/Cedar-watchOS.xcscheme ================================================ ================================================ FILE: CodeSnippetsAndTemplates/AppCodeSnippets/Cedar.xml ================================================ ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/caft-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix caft IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents afterEach { <#content#> } IDECodeSnippetIdentifier 810E8F16-D042-4EAA-A132-AF519E003E6B IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar after each block for Swift IDECodeSnippetTitle Cedar after each - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/caft.codesnippet ================================================ IDECodeSnippetCompletionPrefix caft IDECodeSnippetCompletionScopes All IDECodeSnippetContents afterEach(^{ <#content#> }); IDECodeSnippetIdentifier 280d64a0-d874-2a87-a31e-7b2a8b1db430 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar after each block IDECodeSnippetTitle Cedar after each IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cbef-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cbef IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents beforeEach { <#content#> } IDECodeSnippetIdentifier 33D58ACB-8C55-4ACA-8EAC-02BCE24FCB8D IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar before each block for Swift IDECodeSnippetTitle Cedar before each - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cbef.codesnippet ================================================ IDECodeSnippetCompletionPrefix cbef IDECodeSnippetCompletionScopes All IDECodeSnippetContents beforeEach(^{ <#content#> }); IDECodeSnippetIdentifier baaaea18-96c5-c20d-c011-0d64e4233e2f IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar before each block IDECodeSnippetTitle Cedar before each IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cbl-context.codesnippet ================================================ IDECodeSnippetCompletionPrefix cblcont IDECodeSnippetCompletionScopes All IDECodeSnippetContents itShouldBehaveLike(@"<#shared behavior description#>", ^(NSMutableDictionary *context) { context[@"<#context key#>"] = <#context value#>; }); IDECodeSnippetIdentifier 3EAE8F83-2880-4D4A-BBEE-46D26D2399F5 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetTitle Cedar should behave like with context IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cbl-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cbl IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents itShouldBehaveLike("<#shared behavior description#>") IDECodeSnippetIdentifier D1A4AEB6-E079-417E-889D-91A1A0B57DD6 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetTitle Cedar should behave like - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 0 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cbl.codesnippet ================================================ IDECodeSnippetCompletionPrefix cbl IDECodeSnippetCompletionScopes All IDECodeSnippetContents itShouldBehaveLike(@"<#shared behavior description#>"); IDECodeSnippetIdentifier D6803E25-A620-4020-974E-2A246BD62127 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetTitle Cedar should behave like IDECodeSnippetUserSnippet IDECodeSnippetVersion 0 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cblcont-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cblcont IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents itShouldBehaveLike("<#shared behavior description#>") { context in context["<#context key#>"] = <#context value#> } IDECodeSnippetIdentifier E1094559-F802-489B-9A79-6F281938B0AE IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetTitle Cedar should behave like with context - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 0 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/ccont-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix ccont IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents context("<#subject under test#>") { <#content#> } IDECodeSnippetIdentifier 49E13C68-47D4-4A53-BD2F-CC8C0AC5A7B4 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar context block for Swift IDECodeSnippetTitle Cedar context - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/ccont.codesnippet ================================================ IDECodeSnippetCompletionPrefix ccont IDECodeSnippetCompletionScopes All IDECodeSnippetContents context(@"<#subject under test#>", ^{ <#content#> }); IDECodeSnippetIdentifier 8ea45300-d080-11e0-9572-0800200c9a66 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar context block IDECodeSnippetTitle Cedar context IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cdesc-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cdesc IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents describe("<#subject under test#>") { <#content#> } IDECodeSnippetIdentifier D4EF3325-530D-4873-B90E-D40916A16C3D IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar describe block for Swift IDECodeSnippetTitle Cedar describe - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cdesc.codesnippet ================================================ IDECodeSnippetCompletionPrefix cdesc IDECodeSnippetCompletionScopes All IDECodeSnippetContents describe(@"<#subject under test#>", ^{ <#content#> }); IDECodeSnippetIdentifier 83a5a55c-1161-0f65-164e-5abcd7886588 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar describe block IDECodeSnippetTitle Cedar describe IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cexpandpend-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix PENDING IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents { <#content#> } IDECodeSnippetIdentifier 1EFA7973-08CD-4435-97E7-AC63A6195238 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Expand a PENDING block to implement it IDECodeSnippetTitle Cedar expand pending - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cexpandpend.codesnippet ================================================ IDECodeSnippetCompletionPrefix PENDING IDECodeSnippetCompletionScopes All IDECodeSnippetContents ^{ <#content#> } IDECodeSnippetIdentifier 38223097-1d03-1576-1c24-8d8e5b2547f5 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Expand a PENDING block to implement it IDECodeSnippetTitle Cedar expand pending IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cit-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cit IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents it("should <#expected behavior#>") { <#content#> } IDECodeSnippetIdentifier 99C76A65-B23F-421B-AA52-D3C46E30BC28 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar example block for Swift IDECodeSnippetTitle Cedar example - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cit.codesnippet ================================================ IDECodeSnippetCompletionPrefix cit IDECodeSnippetCompletionScopes All IDECodeSnippetContents it(@"should <#expected behavior#>", ^{ <#content#> }); IDECodeSnippetIdentifier 8e82bfce-c076-3857-3930-a7c16a6372cc IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar example block IDECodeSnippetTitle Cedar example IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/clog-swift.codesnippet ================================================ IDECodeSnippetCompletionScopes All IDECodeSnippetContents print("================>", <#value of interest#>) IDECodeSnippetIdentifier 1AC7A9EF-7EA0-4A7F-B5A4-E749A9940618 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Log to console output for Swift IDECodeSnippetTitle Console log - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 0 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/clog.codesnippet ================================================ IDECodeSnippetCompletionPrefix clog IDECodeSnippetCompletionScopes All IDECodeSnippetContents NSLog(@"================> %@", <#object of interest#>); IDECodeSnippetIdentifier EB810C64-2BB3-471D-A190-BCFCA06B015E IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Log to console output IDECodeSnippetTitle Console log IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cpend-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cpend IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents it("should <#expected behavior#>", PENDING) IDECodeSnippetIdentifier 858980E1-6F1F-4165-9501-F05F737D49F3 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar pending example block for Swift IDECodeSnippetTitle Cedar pending example - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cpend.codesnippet ================================================ IDECodeSnippetCompletionPrefix cpend IDECodeSnippetCompletionScopes All IDECodeSnippetContents it(@"should <#expected behavior#>", PENDING); IDECodeSnippetIdentifier 4b9ce7c4-0a57-188b-a563-34190399aa52 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar pending example block IDECodeSnippetTitle Cedar pending example IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cshare-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix cshare IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents sharedExamplesFor("<#shared behavior description#>") { context in <#content#> } IDECodeSnippetIdentifier 0E3FC2BE-CAB4-4BA6-B8AF-D676588419B0 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar shared examples for Swift IDECodeSnippetTitle Cedar shared example group - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/cshare.codesnippet ================================================ IDECodeSnippetCompletionPrefix cshare IDECodeSnippetCompletionScopes All IDECodeSnippetContents sharedExamplesFor(@"<#shared behavior description#>", ^(NSDictionary *sharedContext) { <#content#> }); IDECodeSnippetIdentifier b813c110-2f41-39ad-5f52-f5e77fae4242 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar shared examples IDECodeSnippetTitle Cedar shared example group IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/csubj-swift.codesnippet ================================================ IDECodeSnippetCompletionPrefix csubj IDECodeSnippetCompletionScopes CodeExpression IDECodeSnippetContents subjectAction { <#action#> } IDECodeSnippetIdentifier E3B41D04-9235-4952-854C-C6851F5213A5 IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Swift IDECodeSnippetSummary Cedar subject action block for Swift IDECodeSnippetTitle Cedar subject action - Swift IDECodeSnippetUserSnippet IDECodeSnippetVersion 0 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/CodeSnippets/csubj.codesnippet ================================================ IDECodeSnippetCompletionPrefix csubj IDECodeSnippetCompletionScopes All IDECodeSnippetContents subjectAction(^{ <#action#> }); IDECodeSnippetIdentifier f81e0e39-8b8a-6629-aa6f-4a19198c413d IDECodeSnippetLanguage Xcode.SourceCodeLanguage.Objective-C IDECodeSnippetSummary Cedar subject action block IDECodeSnippetTitle Cedar subject action IDECodeSnippetUserSnippet IDECodeSnippetVersion 2 isCedarSnippet ================================================ FILE: CodeSnippetsAndTemplates/Templates/File Templates/Cedar/Cedar Spec.xctemplate/Objective-C++/___FILEBASENAME___Spec.mm ================================================ #import #import "___VARIABLE_cedarClass:identifier___.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(___VARIABLE_cedarClass:identifier___Spec) describe(@"___VARIABLE_cedarClass:identifier___", ^{ __block ___VARIABLE_cedarClass:identifier___ *<#object under test#>; beforeEach(^{ }); }); SPEC_END ================================================ FILE: CodeSnippetsAndTemplates/Templates/File Templates/Cedar/Cedar Spec.xctemplate/Swift/___FILEBASENAME___Spec.swift ================================================ import Cedar class ___VARIABLE_cedarClass:identifier___Spec: CDRSpec { override func declareBehaviors() { var <#object under test#>: ___VARIABLE_cedarClass:identifier___! beforeEach { } } } ================================================ FILE: CodeSnippetsAndTemplates/Templates/File Templates/Cedar/Cedar Spec.xctemplate/TemplateInfo.plist ================================================ isCedarTemplate Summary A Cedar Spec Description A Cedar Spec File Kind Xcode.IDEKit.TextSubstitutionFileTemplateKind SortOrder 1 DefaultCompletionName MyClass Options Description The name of the type to spec Identifier cedarClass Name Type to Spec: Required NotPersisted Type text AllowedTypes Swift public.swift-source Objective-C++ public.objective-c-plus-plus-source Default Objective-C++ Description The implementation language Identifier languageChoice MainTemplateFiles Objective-C ___FILEBASENAME___Spec.mm Swift ___FILEBASENAME___Spec.swift Name Language: Required Yes Type popup Values Objective-C++ Swift Default ___VARIABLE_cedarClass:identifier___ Identifier productName Type static ================================================ FILE: English.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: Gemfile ================================================ source "https://rubygems.org" gem 'cucumber' gem 'aruba' gem 'rake' gem 'pry' ================================================ FILE: MIT.LICENSE.txt ================================================ Copyright (c) 2010 Pivotal Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.markdown ================================================ # Cedar [![Build Status](https://travis-ci.org/cedarbdd/cedar.png?branch=master)](https://travis-ci.org/cedarbdd/cedar) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) Cedar is a BDD-style Objective-C testing framework with an expressive matcher DSL and convenient test doubles. ```objc describe(@"Example specs on NSString", ^{ it(@"lowercaseString returns a new string with everything in lower case", ^{ [@"FOOBar" lowercaseString] should equal(@"foobar"); }); it(@"length returns the number of characters in the string", ^{ [@"internationalization" length] should equal(20); }); describe(@"isEqualToString:", ^{ it(@"should return true if the strings are the same", ^{ [@"someString" isEqualToString:@"someString"] should be_truthy; }); it(@"should return false if the strings are not the same", ^{ [@"someString" isEqualToString:@"anotherString"] should be_falsy; }); }); }); ``` # Quick start * Add Cedar to your project via [CocoaPods](https://cocoapods.org/pods/Cedar) (`pod 'Cedar'`), [Carthage](https://github.com/Carthage/Carthage) (`github "cedarbdd/cedar"`), or [another method](https://github.com/cedarbdd/cedar/wiki/Installation#available-installation-methods) * Install the Cedar Xcode file templates using the [Alcatraz package manager](http://alcatraz.io/) or by running this command in a terminal: ``` $ curl -L https://raw.github.com/cedarbdd/cedar/master/install.sh | bash ``` * Or if you want to install from HEAD. Run: ``` $ bash <(echo "set -- --head; $(curl -L https://raw.github.com/cedarbdd/cedar/master/install.sh)") ``` * Restart Xcode * Add new spec files to your project's Test Bundle using the Xcode templates * Start writing specs! # Documentation Documentation can be found on the [Cedar Wiki](https://github.com/cedarbdd/cedar/wiki). # Support and feedback * Search past discussions: [http://groups.google.com/group/cedar-discuss](http://groups.google.com/group/cedar-discuss) * Send an e-mail to the discussion list: [mailto:cedar-discuss@googlegroups.com](mailto:cedar-discuss@googlegroups.com) * View the project backlog on Pivotal Tracker: [http://www.pivotaltracker.com/projects/77775](http://www.pivotaltracker.com/projects/77775). * Follow us on twitter: [@cedarbdd](http://twitter.com/cedarbdd) # Contributing Please read the [Contributor Guide](https://github.com/cedarbdd/cedar/wiki/Contributor-guide) on the wiki. # Maintainers * [Andrew Kitchen](mailto:akitchen@pivotallabs.com) ([akitchen](https://github.com/akitchen)), Pivotal Labs, San Francisco * [Brian Croom](mailto:bcroom@pivotal.io) ([briancroom](https://github.com/briancroom)), Pivotal Labs, Toronto * [Jeff Hui](mailto:jhui@pivotallabs.com) ([jeffh](https://github.com/jeffh)), Pivotal Labs, San Francisco * [Sam Coward](mailto:scoward@pivotallabs.com) ([idoru](https://github.com/idoru)), Pivotal Labs, New York * [Tim Jarratt](mailto:tjarratt@pivotal.io) ([tjarratt](https://github.com/tjarratt)), Pivotal Labs, San Francisco Copyright (c) 2010-2016 Pivotal Labs. This software is licensed under the MIT License. [![Mixpanel](https://api.mixpanel.com/track/?data=CXsiZXZlbnQiOiAiSG9tZSBWaXNpdCIsIA0KICAgIAkJInByb3BlcnRpZXMiOiB7ICAJDQogICAgICAgIAkidG9rZW4iOiAiNmJjZmE3MmQ5OGU2ZjdhZjFkNjQ3YWNmY2Q2NjMwNTEiICAgDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICB9&ip=1&img=1)](http://mixpanel.com) ================================================ FILE: Rakefile ================================================ PROJECT_NAME = "Cedar" APP_IOS_NAME = "Cedar-iOS StaticLib Specs" CONFIGURATION = "Release" SPECS_TARGET_NAME = "Cedar-OSX Specs" UI_SPECS_TARGET_NAME = "Cedar-iOS StaticLib Specs" FOCUSED_SPECS_TARGET_NAME = "Cedar-OSX FocusedSpecs" IOS_STATIC_FRAMEWORK_SPECS_TARGET_NAME = "Cedar-iOS StaticFrameworkSpecs" IOS_DYNAMIC_FRAMEWORK_SPECS_TARGET_NAME = "Cedar-iOS Specs" IOS_SPEC_BUNDLE_SCHEME_NAME = "Cedar-iOS SpecBundle" CEDAR_FRAMEWORK_TARGET_NAME = "Cedar-OSX" CEDAR_IOS_STATIC_FRAMEWORK_TARGET_NAME = "Cedar-iOS StaticFramework" CEDAR_IOS_DYNAMIC_FRAMEWORK_TARGET_NAME = "Cedar-iOS" TEMPLATE_IDENTIFIER_PREFIX = "com.pivotallabs.cedar." TEMPLATE_SENTINEL_KEY = "isCedarTemplate" SNIPPET_SENTINEL_VALUE = "isCedarSnippet" XCODE_TEMPLATES_DIR = "#{ENV['HOME']}/Library/Developer/Xcode/Templates" XCODE_SNIPPETS_DIR = "#{ENV['HOME']}/Library/Developer/Xcode/UserData/CodeSnippets" LATEST_SDK_VERSION = `xcodebuild -showsdks 2>/dev/null | grep iphonesimulator | cut -d ' ' -f 4`.chomp.split("\n").last SDK_VERSION = ENV["CEDAR_SDK_VERSION"] || LATEST_SDK_VERSION SDK_RUNTIME_VERSION = ENV["CEDAR_SDK_RUNTIME_VERSION"] || LATEST_SDK_VERSION PROJECT_ROOT = File.dirname(__FILE__) BUILD_DIR = File.join(PROJECT_ROOT, "build") DERIVED_DATA_DIR = File.join(PROJECT_ROOT, "derivedData") TEMPLATES_DIR = File.join(PROJECT_ROOT, "CodeSnippetsAndTemplates", "Templates") SNIPPETS_DIR = File.join(PROJECT_ROOT, "CodeSnippetsAndTemplates", "CodeSnippets") DIST_STAGING_DIR = "#{BUILD_DIR}/dist" PLISTBUDDY = "/usr/libexec/PlistBuddy" require 'tmpdir' require 'tempfile' require_relative 'scripts/rake/helpers' require_relative 'scripts/rake/tasks' ================================================ FILE: Source/CDRExample.m ================================================ #import "CDRExample.h" #import "CDRSpecHelper.h" #import "CDRReportDispatcher.h" const CDRSpecBlock PENDING = nil; @interface CDRExample (Private) - (void)setState:(CDRExampleState)state; @end @implementation CDRExample @synthesize failure = failure_; + (id)exampleWithText:(NSString *)text andBlock:(CDRSpecBlock)block { return [[[[self class] alloc] initWithText:text andBlock:block] autorelease]; } - (id)initWithText:(NSString *)text andBlock:(CDRSpecBlock)block { if (self = [super initWithText:text]) { block_ = [block copy]; state_ = CDRExampleStateIncomplete; } return self; } - (void)dealloc { self.failure = nil; [block_ release]; [super dealloc]; } #pragma mark CDRExampleBase - (CDRExampleState)state { return state_; } - (NSString *)message { if (self.failure.reason) { return self.failure.reason; } return [super message]; } - (float)progress { if (self.state == CDRExampleStateIncomplete) { return 0.0; } else { return 1.0; } } - (BOOL)isPending { return (self.state == CDRExampleStateIncomplete && block_ == nil) || self.state == CDRExampleStatePending; } - (void)runWithDispatcher:(CDRReportDispatcher *)dispatcher { if (self.state != CDRExampleStateIncomplete) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempt to run example twice: %@", [self fullText]] userInfo:nil] raise]; } [startDate_ release]; startDate_ = [[NSDate alloc] init]; [dispatcher runWillStartExample:self]; if (!self.shouldRun) { self.state = CDRExampleStateSkipped; } else if (self.isPending) { self.state = CDRExampleStatePending; } else { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @try { [parent_ setUp]; if (parent_.subjectActionBlock) { parent_.subjectActionBlock(); } block_(); self.state = CDRExampleStatePassed; } @catch (CDRSpecFailure *x) { self.failure = x; self.state = CDRExampleStateFailed; } @catch (NSObject *x) { self.failure = [CDRSpecFailure specFailureWithRaisedObject:x]; self.state = CDRExampleStateError; } @finally { @try { [parent_ tearDown]; } @catch (NSObject *x) { if (self.state != CDRExampleStateFailed) { self.failure = [CDRSpecFailure specFailureWithRaisedObject:x]; self.state = CDRExampleStateError; } } } [pool drain]; } [endDate_ release]; endDate_ = [[NSDate alloc] init]; [dispatcher runDidFinishExample:self]; [block_ release]; block_ = nil; } #pragma mark Private interface - (void)setState:(CDRExampleState)state { state_ = state; } @end ================================================ FILE: Source/CDRExampleBase.m ================================================ #import "CDRExampleBase.h" #import "CDRSpecHelper.h" #import "CDRReportDispatcher.h" @implementation CDRExampleBase @synthesize text = text_, parent = parent_, focused = focused_, stackAddress = stackAddress_, startDate = startDate_, endDate = endDate_, spec = spec_; - (id)initWithText:(NSString *)text { if (self = [super init]) { text_ = [text retain]; focused_ = NO; } return self; } - (void)dealloc { [text_ release]; [startDate_ release]; [endDate_ release]; self.spec = nil; self.parent = nil; [super dealloc]; } - (void)setUp { } - (void)tearDown { } - (void)runWithDispatcher:(CDRReportDispatcher *)dispatcher { } - (BOOL)shouldRun { BOOL shouldOnlyRunFocused = [CDRSpecHelper specHelper].shouldOnlyRunFocused; return !shouldOnlyRunFocused || (shouldOnlyRunFocused && (self.isFocused || parent_.shouldRun)); } - (BOOL)hasFocusedExamples { return self.isFocused; } - (BOOL)hasChildren { return NO; } - (CDRExampleState)state { return CDRExampleStateIncomplete; } - (NSString *)message { return @""; } - (NSString *)fullText { return [[self fullTextInPieces] componentsJoinedByString:@" "]; } - (NSMutableArray *)fullTextInPieces { if (self.parent && [self.parent respondsToSelector:@selector(hasFullText)] && [self.parent hasFullText]) { NSMutableArray *array = [self.parent fullTextInPieces]; [array addObject:self.text]; return array; } else { return [NSMutableArray arrayWithObject:self.text]; } } - (NSTimeInterval)runTime { return [endDate_ timeIntervalSinceDate:startDate_]; } @end ================================================ FILE: Source/CDRExampleGroup.m ================================================ #import "CDRExampleGroup.h" #import "CDRReportDispatcher.h" @interface CDRExampleGroup (Private) - (void)startObservingExamples; - (void)stopObservingExamples; @end @implementation CDRExampleGroup @synthesize examples = examples_; @synthesize subjectActionBlock = subjectActionBlock_; + (id)groupWithText:(NSString *)text { return [[[[self class] alloc] initWithText: text] autorelease]; } - (id)initWithText:(NSString *)text { return [self initWithText:text isRoot:NO]; } - (id)initWithText:(NSString *)text isRoot:(BOOL)isRoot { if (self = [super initWithText:text]) { beforeBlocks_ = [[NSMutableArray alloc] init]; examples_ = [[NSMutableArray alloc] init]; afterBlocks_ = [[NSMutableArray alloc] init]; isRoot_ = isRoot; } return self; } - (void)dealloc { [afterBlocks_ release]; [examples_ release]; [beforeBlocks_ release]; self.subjectActionBlock = nil; [super dealloc]; } #pragma mark Public interface - (NSString *)description { return [NSString stringWithFormat:@"Example Group: \"%@\"", self.fullText]; } - (CDRSpecBlock)subjectActionBlock { CDRSpecBlock parentSubjectActionBlock = self.parent.subjectActionBlock; if (subjectActionBlock_) { if (parentSubjectActionBlock) { @throw([NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ has more than one subject action block", self] userInfo:nil]); } else { return subjectActionBlock_; } } else { return parentSubjectActionBlock; } } - (void)add:(CDRExampleBase *)example { example.parent = self; [examples_ addObject:example]; } - (void)addBefore:(CDRSpecBlock)block { CDRSpecBlock blockCopy = [block copy]; [beforeBlocks_ addObject:blockCopy]; [blockCopy release]; } - (void)addAfter:(CDRSpecBlock)block { CDRSpecBlock blockCopy = [block copy]; [afterBlocks_ addObject:blockCopy]; [blockCopy release]; } #pragma mark CDRExampleBase - (CDRExampleState)state { if (0 == [examples_ count]) { return CDRExampleStatePending; } CDRExampleState aggregateState = CDRExampleStateIncomplete; for (CDRExampleBase *example in examples_) { aggregateState |= [example state]; } return aggregateState; } - (float)progress { if (0 == [examples_ count]) { return 1.0; } float aggregateProgress = 0.0; for (CDRExampleBase *example in examples_) { aggregateProgress += [example progress]; } return aggregateProgress / [examples_ count]; } - (void)runWithDispatcher:(CDRReportDispatcher *)dispatcher { if (startDate_) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempt to run example group twice: %@", [self fullText]] userInfo:nil] raise]; } [dispatcher runWillStartExampleGroup:self]; [startDate_ release]; startDate_ = [[NSDate alloc] init]; [self startObservingExamples]; [examples_ makeObjectsPerformSelector:@selector(runWithDispatcher:) withObject:dispatcher]; [self stopObservingExamples]; [endDate_ release]; endDate_ = [[NSDate alloc] init]; [dispatcher runDidFinishExampleGroup:self]; [beforeBlocks_ release]; beforeBlocks_ = nil; [afterBlocks_ release]; afterBlocks_ = nil; self.subjectActionBlock = nil; } - (BOOL)hasFocusedExamples { if (self.isFocused) { return YES; } for (CDRExampleBase *example in examples_) { if ([example hasFocusedExamples]) { return YES; } } return NO; } - (BOOL)hasChildren { return [examples_ count] > 0; } #pragma mark CDRExampleParent - (void)setUp { [parent_ setUp]; for (CDRSpecBlock beforeBlock in beforeBlocks_) { beforeBlock(); } } - (void)tearDown { for (CDRSpecBlock afterBlock in afterBlocks_) { afterBlock(); } [parent_ tearDown]; } - (BOOL)hasFullText { return !isRoot_; } #pragma mark KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { [self willChangeValueForKey:@"state"]; [self didChangeValueForKey:@"state"]; } #pragma mark Private interface - (void)startObservingExamples { for (id example in examples_) { [example addObserver:self forKeyPath:@"state" options:0 context:NULL]; } } - (void)stopObservingExamples { for (id example in examples_) { [example removeObserver:self forKeyPath:@"state"]; } } @end ================================================ FILE: Source/CDRFunctions.m ================================================ #import #import #import "CDRSpec.h" #import "CDRHooks.h" #import "CDRExampleGroup.h" #import "CDRExampleReporter.h" #import "CDRDefaultReporter.h" #import "CDRSpecHelper.h" #import "CDRFunctions.h" #import "CDRReportDispatcher.h" #import "CDROTestNamer.h" #import "CDRVersion.h" #import "CDRSpecRun.h" #import "CDRStateTracker.h" static NSString * const CDRBuildVersionKey = @"CDRBuildVersionSHA"; #pragma mark - Helpers BOOL CDRClassIsOfType(Class class, const char * const className) { Protocol * protocol = NSProtocolFromString([NSString stringWithCString:className encoding:NSUTF8StringEncoding]); if (strcmp(className, class_getName(class))) { while (class) { if (class_conformsToProtocol(class, protocol)) { return YES; } class = class_getSuperclass(class); } } return NO; } void CDREnumerateClasses(void (^block)(Class class, BOOL *stop)) { unsigned int numberOfClasses = objc_getClassList(NULL, 0); Class classes[numberOfClasses]; numberOfClasses = objc_getClassList(classes, numberOfClasses); BOOL stop = NO; for (unsigned int i = 0; i < numberOfClasses && !stop; ++i) { block(classes[i], &stop); } } NSArray *CDRSelectClasses(BOOL (^classSelectionPredicate)(Class class)) { NSMutableArray *selectedClasses = [NSMutableArray array]; CDREnumerateClasses(^(Class class, BOOL *stop) { if (classSelectionPredicate(class)) { [class retain]; [selectedClasses addObject:class]; [class release]; } }); return selectedClasses; } Class CDRFirstOfClasses(BOOL (^classSelectionPredicate)(Class class)) { __block Class firstClass = Nil; CDREnumerateClasses(^(Class class, BOOL *stop) { if (classSelectionPredicate(class)) { firstClass = class; *stop = YES; } }); return firstClass; } NSString *CDRVersionString() { NSString *versionDetails = nil; #if COCOAPODS versionDetails = @"from CocoaPods"; #endif if (!versionDetails) { NSBundle *cedarFrameworkBundle = [NSBundle bundleForClass:[CDRSpec class]]; versionDetails = [cedarFrameworkBundle objectForInfoDictionaryKey:CDRBuildVersionKey]; } return versionDetails ? [CDRVersion stringByAppendingFormat:@" (%@)", versionDetails] : CDRVersion; } BOOL (^CDRClassIsSpecPredicate)(Class class) = ^(Class class) { return CDRClassIsOfType(class, "CDRSpec"); }; NSBundle *CDRBundleContainingSpecs() { Class specClass = CDRFirstOfClasses(CDRClassIsSpecPredicate); return [NSBundle bundleForClass:specClass ?: [CDRSpec class]]; } #pragma mark - Globals void CDRDefineSharedExampleGroups() { NSArray *sharedExampleGroupPoolClasses = CDRSelectClasses(^(Class class) { return CDRClassIsOfType(class, "CDRSharedExampleGroupPool"); }); for (Class class in sharedExampleGroupPoolClasses) { CDRSharedExampleGroupPool *sharedExampleGroupPool = [[class alloc] init]; [sharedExampleGroupPool declareSharedExampleGroups]; [sharedExampleGroupPool release]; } } BOOL CDRClassHasClassMethod(Class class, SEL selector) { if (class_conformsToProtocol(class, @protocol(CDRHooks))) { return !!class_getClassMethod(class, selector); } return NO; } NSArray *CDRHooksClassesWithSelector(SEL selector) { return CDRSelectClasses(^BOOL(Class class) { return class_conformsToProtocol(class, @protocol(CDRHooks)) && !!class_getClassMethod(class, selector); }); } void CDRDefineGlobalBeforeAndAfterEachBlocks() { [CDRSpecHelper specHelper].globalBeforeEachClasses = CDRHooksClassesWithSelector(@selector(beforeEach)); [CDRSpecHelper specHelper].globalAfterEachClasses = CDRHooksClassesWithSelector(@selector(afterEach)); } #pragma mark - Reporters NSArray *CDRReporterClassesFromEnv(const char *defaultReporterClassName) { const char *reporterClassNamesCsv = getenv("CEDAR_REPORTER_CLASS"); if (!reporterClassNamesCsv) { reporterClassNamesCsv = defaultReporterClassName; } NSString *objCClassNames = [NSString stringWithUTF8String:reporterClassNamesCsv]; NSArray *reporterClassNames = [objCClassNames componentsSeparatedByString:@","]; NSMutableArray *reporterClasses = [NSMutableArray arrayWithCapacity:[reporterClassNames count]]; for (NSString *reporterClassName in reporterClassNames) { Class reporterClass = [NSClassFromString(reporterClassName) retain]; if (!reporterClass) { printf("***** The specified reporter class \"%s\" does not exist. *****\n", [reporterClassName cStringUsingEncoding:NSUTF8StringEncoding]); return nil; } [reporterClasses addObject:reporterClass]; [reporterClass release]; } return reporterClasses; } NSArray *CDRReportersFromEnv(const char *defaultReporterClassName) { NSArray *reporterClasses = CDRReporterClassesFromEnv(defaultReporterClassName); NSMutableArray *reporters = [NSMutableArray arrayWithCapacity:reporterClasses.count]; for (Class reporterClass in reporterClasses) { id reporter = nil; if ([reporterClass instancesRespondToSelector:@selector(initWithCedarVersion:)]) { reporter = [[[reporterClass alloc] initWithCedarVersion:CDRVersionString()] autorelease]; } else { reporter = [[[reporterClass alloc] init] autorelease]; } [reporters addObject:reporter]; } return reporters; } #pragma mark - Spec running void CDRSuppressStandardPipesWhileLoadingClasses() { if (getenv("CEDAR_VERBOSE")) { int saved_stdout = dup(STDOUT_FILENO); int saved_stderr = dup(STDERR_FILENO); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); unsigned int count = 0; Class *classes = objc_copyClassList(&count); for (int i = 0; i < count; i++) { if (class_respondsToSelector(classes[i], @selector(initialize))) { [classes[i] class]; } } free(classes); dup2(saved_stdout, STDOUT_FILENO); dup2(saved_stderr, STDERR_FILENO); } } NSArray *CDRSpecClassesToRun() { char *envSpecClassNames = getenv("CEDAR_SPEC_CLASSES"); if (envSpecClassNames) { NSArray *specClassNames = [[NSString stringWithUTF8String:envSpecClassNames] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSMutableArray *specClassesToRun = [NSMutableArray arrayWithCapacity:specClassNames.count]; for (NSString *className in specClassNames) { Class specClass = NSClassFromString(className); if (specClass) { [specClassesToRun addObject:specClass]; } } return [[specClassesToRun copy] autorelease]; } return CDRSelectClasses(CDRClassIsSpecPredicate); } NSArray *CDRSpecsFromSpecClasses(NSArray *specClasses) { NSMutableArray *specs = [NSMutableArray arrayWithCapacity:specClasses.count]; for (Class class in specClasses) { CDRSpec *spec = [[class alloc] init]; [spec defineBehaviors]; [specs addObject:spec]; [spec release]; } return specs; } void CDRMarkFocusedExamplesInSpecs(NSArray *specs) { char *envSpecFile = getenv("CEDAR_SPEC_FILE"); if (envSpecFile) { NSArray *components = [[NSString stringWithUTF8String:envSpecFile] componentsSeparatedByString:@":"]; for (CDRSpec *spec in specs) { if ([spec.fileName isEqualToString:[components objectAtIndex:0]]) { [spec markAsFocusedClosestToLineNumber:[[components objectAtIndex:1] intValue]]; } } } for (CDRSpec *spec in specs) { CDRSpecHelper.specHelper.shouldOnlyRunFocused |= spec.rootGroup.hasFocusedExamples; } } void CDRMarkXcodeFocusedExamplesInSpecs(NSArray *specs, NSArray *arguments) { // Xcode gives us this: // App ... -SenTest All TestBundle.xctest // when not focused and // App ... -SenTest /,/ TestBundle.xctest // when focused in the arguments list. // // The list defaults to the tests to focused UNLESS "-SenTestInvertScope YES" is // provided, in which case the tests provided should be excluded from running. NSUInteger index = [arguments indexOfObject:@"-SenTest"]; if (index == NSNotFound) { return; } NSString *examplesArgument = [arguments objectAtIndex:index + 1]; BOOL isExclusive = NO; index = [arguments indexOfObject:@"-SenTestInvertScope"]; if (index != NSNotFound) { isExclusive = [@"YES" isEqual:[arguments objectAtIndex:index + 1]]; } // TODO: should we handle the InvertScope + All case? if ([@[@"Self", @"All"] containsObject:examplesArgument]) { return; } NSMutableDictionary *testMethodNamesBySpecClass = [NSMutableDictionary dictionary]; for (NSString *testName in [examplesArgument componentsSeparatedByString:@","]) { NSArray *components = [testName componentsSeparatedByString:@"/"]; if (components.count > 1) { NSString *specClass = [components objectAtIndex:0]; NSString *testMethod = [components objectAtIndex:1]; NSMutableSet *testMethods = [testMethodNamesBySpecClass objectForKey:specClass]; if (!testMethods) { testMethods = [NSMutableSet set]; [testMethodNamesBySpecClass setObject:testMethods forKey:specClass]; } [testMethods addObject:testMethod]; } } CDROTestNamer *testNamer = [[CDROTestNamer alloc] init]; for (CDRSpec *spec in specs) { NSSet *methods = [testMethodNamesBySpecClass objectForKey:NSStringFromClass([spec class])]; for (CDRExampleBase *example in [spec allChildren]) { if (example.hasChildren) { continue; } example.focused = (isExclusive != [methods containsObject:[testNamer methodNameForExample:example]]); } } [testNamer release]; for (CDRSpec *spec in specs) { CDRSpecHelper.specHelper.shouldOnlyRunFocused |= spec.rootGroup.hasFocusedExamples; } } NSArray *CDRShuffleItemsInArrayWithSeed(NSArray *sortedItems, unsigned int seed) { NSMutableArray *shuffledItems = [sortedItems mutableCopy]; srand(seed); for (int i=0; i < shuffledItems.count; i++) { NSUInteger idx = rand() % shuffledItems.count; [shuffledItems exchangeObjectAtIndex:i withObjectAtIndex:idx]; } return [shuffledItems autorelease]; } NSArray *CDRPermuteSpecClassesWithSeed(NSArray *unsortedSpecClasses, unsigned int seed) { NSMutableArray *sortedSpecClasses = unsortedSpecClasses.mutableCopy; [sortedSpecClasses sortUsingComparator:^NSComparisonResult(Class class1, Class class2) { return [NSStringFromClass(class1) compare:NSStringFromClass(class2)]; }]; return CDRShuffleItemsInArrayWithSeed(sortedSpecClasses, seed); } unsigned int CDRGetRandomSeed() { unsigned int seed = time(NULL) % 100000 + 2; if (getenv("CEDAR_RANDOM_SEED")) { seed = [[NSString stringWithUTF8String:getenv("CEDAR_RANDOM_SEED")] intValue]; } return seed; } void __attribute__((weak)) __gcov_flush(void) { } int CDRRunSpecsWithCustomExampleReporters(NSArray *reporters) { @autoreleasepool { CDRStateTracker *stateTracker = [[[CDRStateTracker alloc] init] autorelease]; CDRSpecRun *run = [[CDRSpecRun alloc] initWithStateTracker:stateTracker exampleReporters:reporters]; int result = [run performSpecRun:^{ [run.rootGroups makeObjectsPerformSelector:@selector(runWithDispatcher:) withObject:run.dispatcher]; }]; [run release]; __gcov_flush(); return result; } } NSArray *CDRReportersToRun() { const char *defaultReporterClassName = "CDRDefaultReporter"; BOOL isTestBundle = objc_getClass("SenTestProbe") || objc_getClass("XCTestProbe"); if (isTestBundle) { // Cedar for Test Bundles hooks into XCTest's test reporting system. defaultReporterClassName = "CDRBufferedDefaultReporter"; } return CDRReportersFromEnv(defaultReporterClassName); } int CDRRunSpecs() { @autoreleasepool { NSArray *reporters = CDRReportersToRun(); if (![reporters count]) { return -999; } else { return CDRRunSpecsWithCustomExampleReporters(reporters); } } } NSString *CDRGetTestBundleExtension() { NSString *extension = nil;; NSArray *arguments = [[NSProcessInfo processInfo] arguments]; NSSet *xctestFlags = [NSSet setWithArray:@[@"-XCTest", @"-XCTestScopeFile"]]; if ([xctestFlags intersectsSet:[NSSet setWithArray:arguments]]) { extension = @".xctest"; } else if ([arguments containsObject:@"-SenTest"]) { extension = @".octest"; } else if ((BOOL)NSClassFromString(@"XCTestCase")) { extension = @".xctest"; } return extension; } ================================================ FILE: Source/CDRNil.m ================================================ #import "CDRNil.h" @implementation CDRNil + (instancetype)nilObject { return [[[self alloc] init] autorelease]; } - (BOOL)isEqual:(id)object { return object==self || [object isMemberOfClass:[self class]]; } - (NSString *)description { return @""; } - (id)copyWithZone:(NSZone *)zone { return [self retain]; } @end ================================================ FILE: Source/CDRRunState.m ================================================ #import "CDRRunState.h" static CedarRunState CDRCurrentRunState = CedarRunStateNotYetStarted; CedarRunState CDRCurrentState() { return CDRCurrentRunState; } void CDRSetCurrentRunState(CedarRunState runState) { CDRCurrentRunState = runState; } ================================================ FILE: Source/CDRRuntimeUtilities.m ================================================ #import "CDRRuntimeUtilities.h" #import static void CDRCopyProtocolsFromClass(Class sourceClass, Class destinationClass) { unsigned int count = 0; Protocol **protocols = class_copyProtocolList(sourceClass, &count); for (unsigned int i = 0; i < count; i++) { class_addProtocol(destinationClass, protocols[i]); } free(protocols); } static void CDRCopyInstanceMethodsFromClass(Class sourceClass, Class destinationClass) { unsigned int count = 0; Method *instanceMethods = class_copyMethodList(sourceClass, &count); for (unsigned int i = 0; i < count; i++) { Method m = instanceMethods[i]; BOOL wasAdded = class_addMethod(destinationClass, method_getName(m), method_getImplementation(m), method_getTypeEncoding(m)); if (!wasAdded) { class_replaceMethod(destinationClass, method_getName(m), method_getImplementation(m), method_getTypeEncoding(m)); } } free(instanceMethods); } static void CDRCopyInstanceVariablesFromClass(Class sourceClass, Class destinationClass) { unsigned int count = 0; Ivar *instanceVars = class_copyIvarList(sourceClass, &count); for (unsigned int i = 0; i < count; i++) { Ivar v = instanceVars[i]; NSUInteger size = 0, align = 0; NSGetSizeAndAlignment(ivar_getTypeEncoding(v), &size, &align); class_addIvar(destinationClass, ivar_getName(v), size, align, ivar_getTypeEncoding(v)); } free(instanceVars); } static void CDRCopyPropertiesFromClass(Class sourceClass, Class destinationClass) { unsigned int count = 0; objc_property_t *properties = class_copyPropertyList(sourceClass, &count); for (unsigned int i = 0; i < count; i++) { objc_property_t property = properties[i]; unsigned int attrCount = 0; objc_property_attribute_t *attributes = property_copyAttributeList(property, &attrCount); class_addProperty(destinationClass, property_getName(property), attributes, attrCount); free(attributes); } free(properties); } static void CDRCopyClassMethodsFromClass(Class sourceClass, Class destinationClass) { Class metaSourceClass = object_getClass(sourceClass); Class metaDestinationClass = object_getClass(destinationClass); CDRCopyInstanceMethodsFromClass(metaSourceClass, metaDestinationClass); } void CDRCopyClassInternalsFromClass(Class sourceClass, Class destinationClass) { CDRCopyProtocolsFromClass(sourceClass, destinationClass); CDRCopyPropertiesFromClass(sourceClass, destinationClass); CDRCopyInstanceVariablesFromClass(sourceClass, destinationClass); CDRCopyInstanceMethodsFromClass(sourceClass, destinationClass); CDRCopyClassMethodsFromClass(sourceClass, destinationClass); } @implementation CDRRuntimeUtilities + (Class)createMixinSubclassOf:(Class)parentClass newClassName:(NSString *)newClassName templateClass:(Class)templateClass { size_t size = class_getInstanceSize(templateClass) - class_getInstanceSize([NSObject class]); Class newSubclass = objc_allocateClassPair(parentClass, [newClassName UTF8String], size); CDRCopyClassInternalsFromClass(templateClass, newSubclass); objc_registerClassPair(newSubclass); return newSubclass; } @end ================================================ FILE: Source/CDRSharedExampleGroupPool.m ================================================ #import "CDRSharedExampleGroupPool.h" #import "CDRSpecHelper.h" #import "CDRSpec.h" #import "CDRExampleGroup.h" #import "CDRSpecFailure.h" extern CDRSpec *CDR_currentSpec; @interface CDRSpecHelper (CDRSharedExampleGroupPoolFriend) @property (nonatomic, retain, readonly) NSMutableDictionary *sharedExampleGroups; @end void sharedExamplesFor(NSString *groupName, CDRSharedExampleGroupBlock block) { [[[CDRSpecHelper specHelper] sharedExampleGroups] setObject:[[block copy] autorelease] forKey:groupName]; } CDR_OVERLOADABLE void itShouldBehaveLike(NSString *groupName) { itShouldBehaveLike(groupName, (CDRSharedExampleContextProviderBlock)NULL); } CDR_OVERLOADABLE void itShouldBehaveLike(NSString *groupName, CDRSharedExampleContextProviderBlock contextBlock) { CDRSharedExampleGroupBlock sharedExampleGroupBlock = [[[SpecHelper specHelper] sharedExampleGroups] objectForKey:groupName]; if (!sharedExampleGroupBlock) { NSString *message = [NSString stringWithFormat:@"Unknown shared example group with description: '%@'", groupName]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:message userInfo:nil] raise]; } CDRExampleGroup *parentGroup = CDR_currentSpec.currentGroup; CDR_currentSpec.currentGroup = [CDRExampleGroup groupWithText:[NSString stringWithFormat:@"(as %@)", groupName]]; [parentGroup add:CDR_currentSpec.currentGroup]; if (contextBlock) { [CDR_currentSpec.currentGroup addBefore:^{ contextBlock([CDRSpecHelper specHelper].sharedExampleContext); }]; } sharedExampleGroupBlock((CDRSharedExampleContext *)[CDRSpecHelper specHelper].sharedExampleContext); CDR_currentSpec.currentGroup = parentGroup; } @implementation CDRSharedExampleGroupPool @end ================================================ FILE: Source/CDRSpec.m ================================================ #import #import "CDRSpec.h" #import "CDRExample.h" #import "CDRRunState.h" #import "CDRSpecHelper.h" #import "CDRSpecFailure.h" #import "CDRExampleGroup.h" #import "CDRSymbolicator.h" #define with_stack_address(b) \ ((b.stackAddress = CDRCallerStackAddress()), b) CDRSpec *CDR_currentSpec; #pragma mark - Spec Validation // runs validation when it(), context(), describe() are invoked // generally this is a useful feature, but you may disable it if you // care to do metaprogramming with Cedar specs // (or other usecases we couldn't imagine). BOOL CDR_validateSpecs = YES; void CDRDisableSpecValidation() { CDR_validateSpecs = NO; } void CDREnableSpecValidation() { CDR_validateSpecs = YES; } #pragma mark - static vars static void(^placeholderPendingTestBlock)() = ^{ BOOL originalState = CDR_validateSpecs; CDR_validateSpecs = NO; it(@"is pending", PENDING); CDR_validateSpecs = originalState; }; #pragma mark - public API void beforeEach(CDRSpecBlock block) { [CDR_currentSpec.currentGroup addBefore:block]; } void afterEach(CDRSpecBlock block) { [CDR_currentSpec.currentGroup addAfter:block]; } void ensureCurrentSpecExists(NSString *functionName) { if (!CDR_validateSpecs) { return; } if (CDR_currentSpec == nil) { NSString * reason = [NSString stringWithFormat:@"%@() was invoked outside of a spec. It may only be called when a spec has been defined with SPEC_BEGIN and SPEC_END macros.", functionName]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } } void ensureTestsAreNotYetRunning(NSString *functionName) { if (!CDR_validateSpecs) { return; } switch (CDRCurrentState()) { case CedarRunStateNotYetStarted: // exceedingly unlikely [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"%@() was invoked BEFORE cedar started running at all. It's unclear how this happened, but this probably represents a bug in your tests. (Please consider opening a github issue if you're fairly certain your test setup is correct)" userInfo:nil] raise]; break; case CedarRunStatePreparingTests: // happy path, no-op, we should hit this branch 100% of the time break; case CedarRunStateRunningTests: { // someone done goofed NSString * reason = [NSString stringWithFormat:@"%@() was invoked during a test run. Make sure your '%@()' is not inside of an it() block.", functionName, functionName]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; break; } case CedarRunStateFinished: // someone ... REALLY done goofed [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"%@() was invoked AFTER cedar finished running all its tests. It's unclear how this happened, but this probably represents a bug in your tests. (Please consider opening a github issue if you're fairly certain your test setup is correct)" userInfo:nil] raise]; break; } } CDRExampleGroup *groupFromSpecBlock(NSString *text, CDRSpecBlock block) { if (!block) { return groupFromSpecBlock(text, placeholderPendingTestBlock); } CDRExampleGroup *parentGroup = CDR_currentSpec.currentGroup; CDRExampleGroup *group = [CDRExampleGroup groupWithText:text]; [parentGroup add:group]; CDR_currentSpec.currentGroup = group; @try { block(); } @catch (CDRSpecFailure *failure) { NSString *reason = [NSString stringWithFormat:@"Caught a spec failure before the specs began to run. Did you forget to put your assertion into an `it` block?. The failure was:\n%@", failure]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } if ([group.examples count] == 0) { block = placeholderPendingTestBlock; block(); } CDR_currentSpec.currentGroup = parentGroup; return group; } CDRExampleGroup * describe(NSString *text, CDRSpecBlock block) { ensureCurrentSpecExists(@"describe"); ensureTestsAreNotYetRunning(@"describe"); CDRExampleGroup *group = groupFromSpecBlock(text, block); return with_stack_address(group); } CDRExampleGroup* context(NSString *text, CDRSpecBlock block) { ensureCurrentSpecExists(@"context"); ensureTestsAreNotYetRunning(@"context"); CDRExampleGroup *group = groupFromSpecBlock(text, block); return with_stack_address(group); } void subjectAction(CDRSpecBlock block) { CDR_currentSpec.currentGroup.subjectActionBlock = block; } CDRExample * it(NSString *text, CDRSpecBlock block) { ensureCurrentSpecExists(@"it"); ensureTestsAreNotYetRunning(@"it"); CDRExample *example = [CDRExample exampleWithText:text andBlock:block]; [CDR_currentSpec.currentGroup add:example]; return with_stack_address(example); } #pragma mark - Pending CDRExampleGroup * xdescribe(NSString *text, CDRSpecBlock block) { CDRExampleGroup *group = describe(text, placeholderPendingTestBlock); return with_stack_address(group); } CDRExampleGroup * xcontext(NSString *text, CDRSpecBlock block) { CDRExampleGroup *group = context(text, placeholderPendingTestBlock); return with_stack_address(group); } CDRExample * xit(NSString *text, CDRSpecBlock block) { CDRExample *example = it(text, PENDING); return with_stack_address(example); } #pragma mark - Focused CDRExampleGroup * fdescribe(NSString *text, CDRSpecBlock block) { CDRExampleGroup *group = describe(text, block); group.focused = YES; return with_stack_address(group); } CDRExampleGroup * fcontext(NSString *text, CDRSpecBlock block) { CDRExampleGroup *group = context(text, block); group.focused = YES; return with_stack_address(group); } CDRExample * fit(NSString *text, CDRSpecBlock block) { CDRExample *example = it(text, block); example.focused = YES; return with_stack_address(example); } void fail(NSString *reason) { [[CDRSpecFailure specFailureWithReason:[NSString stringWithFormat:@"Failure: %@", reason]] raise]; } /* Please be aware that CDRSpec+XCTestSupport does dynamic subclassing using this class as a mixin. * All ivars must be dynamically looked up. See that category for examples. * * DO NOT use synthesized properties - they will crash when running inside a test bundle. */ @implementation CDRSpec @synthesize rootGroup = rootGroup_, currentGroup = currentGroup_, symbolicator = symbolicator_, fileName = fileName_; #pragma mark Memory - (void)dealloc { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" self.rootGroup = nil; self.currentGroup = nil; self.fileName = nil; self.symbolicator = nil; #pragma clang diagnostic pop [super dealloc]; } - (void)commonInit { NSString *text = self.class.description; self.rootGroup = [[[CDRExampleGroup alloc] initWithText:text isRoot:YES] autorelease]; self.rootGroup.parent = [CDRSpecHelper specHelper]; self.currentGroup = self.rootGroup; self.symbolicator = [[[CDRSymbolicator alloc] init] autorelease]; } - (instancetype)init { self = [super init]; if (self) { [self commonInit]; } return self; } - (void)defineBehaviors { CDR_currentSpec = self; [self declareBehaviors]; CDR_currentSpec = nil; [self markSpecClassForExampleBase:self.rootGroup]; } - (void)markSpecClassForExampleBase:(CDRExampleBase *)example { example.spec = self; if (example.hasChildren) { for (CDRExampleBase *childExample in [(CDRExampleGroup *)example examples]) { [self markSpecClassForExampleBase:childExample]; } } } - (void)markAsFocusedClosestToLineNumber:(NSUInteger)lineNumber { NSArray *children = self.allChildren; if (children.count == 0) return; NSMutableArray *addresses = [NSMutableArray array]; for (CDRExampleBase *child in children) { [addresses addObject:[NSNumber numberWithUnsignedInteger:child.stackAddress]]; } // Use symbolication to find out locations of examples. // We cannot turn describe/it/context into macros because: // - making them non-function macros pollutes namespace // - making them function macros causes xcode to highlight // wrong lines of code if there are errors present in the code // - also __LINE__ is unrolled from the outermost block // which causes incorrect values NSError *error = nil; if ([self.symbolicator symbolicateAddresses:addresses error:&error]) { NSUInteger bestAddressIndex = [children indexOfObject:self.rootGroup]; // Matches closest example/group located on or below specified line number // (only takes into account start of an example/group) for (NSInteger i = 0, shortestDistance = -1; i < addresses.count; i++) { NSInteger address = [[addresses objectAtIndex:i] integerValue]; NSInteger distance = lineNumber - [self.symbolicator lineNumberForStackAddress:address]; if (distance >= 0 && (distance < shortestDistance || shortestDistance == -1) ) { bestAddressIndex = i; shortestDistance = distance; } } [[children objectAtIndex:bestAddressIndex] setFocused:YES]; } else if (error.domain == kCDRSymbolicatorErrorDomain) { if (error.code == kCDRSymbolicatorErrorNotAvailable) { printf("Spec location symbolication is not available.\n"); } else if (error.code == kCDRSymbolicatorErrorNotSuccessful) { NSString *details = [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey]; printf("Spec location symbolication was not successful.\n" "Details:\n%s\n", details.UTF8String); } else { printf("Spec location symbolication failed.\n"); } } } - (NSArray *)allChildren { NSMutableArray *unseenChildren = [NSMutableArray arrayWithObject:self.rootGroup]; NSMutableArray *seenChildren = [NSMutableArray array]; while (unseenChildren.count > 0) { CDRExampleBase *child = [unseenChildren lastObject]; [unseenChildren removeLastObject]; if (child.hasChildren) { [unseenChildren addObjectsFromArray:[(CDRExampleGroup *)child examples]]; } [seenChildren addObject:child]; } return seenChildren; } @end ================================================ FILE: Source/CDRSpecFailure.m ================================================ #import "CDRSpecFailure.h" #import "CDRSymbolicator.h" #import @interface CDRSpecFailure () + (void)extractReason:(NSString **)reason fileName:(NSString **)fileName lineNumber:(int *)lineNumber fromObject:(NSObject *)object; + (BOOL)extractReason:(NSString **)reason fileName:(NSString **)fileName lineNumber:(int *)lineNumber fromString:(NSString *)string; @end @implementation CDRSpecFailure @synthesize fileName = fileName_, lineNumber = lineNumber_, callStackReturnAddresses = callStackReturnAddresses_; + (id)specFailureWithReason:(NSString *)reason { return [[[self alloc] initWithReason:reason] autorelease]; } + (id)specFailureWithReason:(NSString *)reason fileName:(NSString *)fileName lineNumber:(int)lineNumber { return [[[self alloc] initWithReason:reason fileName:fileName lineNumber:lineNumber] autorelease]; } + (id)specFailureWithRaisedObject:(NSObject *)object { return [[[self alloc] initWithRaisedObject:object] autorelease]; } - (id)initWithReason:(NSString *)reason { return [self initWithRaisedObject:reason]; } - (id)initWithReason:(NSString *)reason fileName:(NSString *)fileName lineNumber:(int)lineNumber { if ((self = [super initWithName:@"Spec Failure" reason:reason userInfo:nil])) { fileName_ = [fileName retain]; lineNumber_ = lineNumber; } return self; } - (id)initWithRaisedObject:(NSObject *)object { NSString *fileName = nil; int lineNumber; NSString *reason = nil; [[self class] extractReason:&reason fileName:&fileName lineNumber:&lineNumber fromObject:object]; if ((self = [super initWithName:@"Spec Failure" reason:reason userInfo:nil])) { fileName_ = [fileName retain]; lineNumber_ = lineNumber; // NSException subclasses tend to have // -callStackReturnAddresses and -callStackSymbols. if ([object respondsToSelector:@selector(callStackReturnAddresses)]) { callStackReturnAddresses_ = [[(id)object callStackReturnAddresses] retain]; } } return self; } - (void)dealloc { [fileName_ release]; [callStackReturnAddresses_ release]; [super dealloc]; } - (NSString *)description { if (self.fileName) { return [NSString stringWithFormat:@"%@:%d %@", self.fileName, self.lineNumber, self.reason]; } return self.reason; } - (NSString *)callStackSymbolicatedSymbols:(NSError **)error { if (!self.callStackReturnAddresses) return nil; CDRSymbolicator *symbolicator = [[[CDRSymbolicator alloc] init] autorelease]; NSMutableString *result = nil; NSError *symbolicationError = nil; if ([symbolicator symbolicateAddresses:self.callStackReturnAddresses error:&symbolicationError]) { result = [NSMutableString stringWithString:@"Call stack:\n"]; BOOL previousAddressWasUnknown = NO; for (int i=0; i < self.callStackReturnAddresses.count; i++) { NSUInteger address = [[self.callStackReturnAddresses objectAtIndex:i] unsignedIntegerValue]; NSString *fileName = [symbolicator fileNameForStackAddress:address]; unsigned long lineNumber = [symbolicator lineNumberForStackAddress:address]; if (fileName) { previousAddressWasUnknown = NO; [result appendFormat:@" *%@:%lu\n", fileName, lineNumber]; } else if (!previousAddressWasUnknown) { previousAddressWasUnknown = YES; [result appendString:@" ...\n"]; } } } else if (error && symbolicationError) { *error = symbolicationError; } return result; } #pragma mark - Private Interface + (void)extractReason:(NSString **)reason fileName:(NSString **)fileName lineNumber:(int *)lineNumber fromObject:(NSObject *)object { if ([object isKindOfClass:[NSException class]]) { NSDictionary *userInfo = [(NSException *)object userInfo]; if ([userInfo objectForKey:@"fileName"] && [userInfo objectForKey:@"lineNumber"]) { *fileName = [userInfo objectForKey:@"fileName"]; *lineNumber = [[userInfo objectForKey:@"lineNumber"] intValue]; *reason = [(NSException *)object reason]; return; } } if ([object isKindOfClass:[NSString class]]) { if ([self extractReason:reason fileName:fileName lineNumber:lineNumber fromString:(NSString *)object]) { return; } } *lineNumber = 0; *reason = [object description]; } + (BOOL)extractReason:(NSString **)reason fileName:(NSString **)fileName lineNumber:(int *)lineNumber fromString:(NSString *)string { static const char *variations[] = { "(.+):([[:digit:]]+)[[:space:]]+(.*)", // File.m:123 reason "(.+)\\(([[:digit:]]+)\\):?[[:space:]]+(.*)" // File.m(123): reason }; const char *buf = [string UTF8String]; for (int i=0; i<2; ++i) { regex_t rx; regmatch_t *matches; regcomp(&rx, variations[i], REG_EXTENDED); matches = (regmatch_t *)malloc((rx.re_nsub+1) * sizeof(regmatch_t)); int result = regexec(&rx, buf, rx.re_nsub+1, matches, 0); if (!result) { *fileName = [[[NSString alloc] initWithBytes:(buf + matches[1].rm_so) length:(NSInteger)(matches[1].rm_eo - matches[1].rm_so) encoding:NSUTF8StringEncoding] autorelease]; *lineNumber = [[[[NSString alloc] initWithBytes:(buf + matches[2].rm_so) length:(NSInteger)(matches[2].rm_eo - matches[2].rm_so) encoding:NSUTF8StringEncoding] autorelease] intValue]; *reason = [[[NSString alloc] initWithBytes:(buf + matches[3].rm_so) length:(NSInteger)(matches[3].rm_eo - matches[3].rm_so) encoding:NSUTF8StringEncoding] autorelease]; } free(matches); regfree(&rx); if (!result) return YES; } return NO; } @end ================================================ FILE: Source/CDRSpecHelper.m ================================================ #import "CDRSpecHelper.h" static CDRSpecHelper *specHelper__; @interface CDRSpecHelper () @property (nonatomic, retain, readwrite) NSMutableDictionary *sharedExampleGroups, *sharedExampleContext; @end @implementation CDRSpecHelper @synthesize sharedExampleGroups = sharedExampleGroups_, sharedExampleContext = sharedExampleContext_, globalBeforeEachClasses = globalBeforeEachClasses_, globalAfterEachClasses = globalAfterEachClasses_, shouldOnlyRunFocused = shouldOnlyRunFocused_; + (id)specHelper { if (!specHelper__) { specHelper__ = [[CDRSpecHelper alloc] init]; } return specHelper__; } - (id)init { if (self = [super init]) { self.sharedExampleGroups = [NSMutableDictionary dictionary]; self.sharedExampleContext = [NSMutableDictionary dictionary]; self.shouldOnlyRunFocused = NO; } return self; } - (void)dealloc { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" self.sharedExampleGroups = nil; self.sharedExampleContext = nil; self.globalBeforeEachClasses = nil; self.globalAfterEachClasses = nil; #pragma clang diagnostic pop [super dealloc]; } #pragma mark CDRExampleParent - (BOOL)shouldRun { return NO; } - (void)setUp { if ([self respondsToSelector:@selector(beforeEach)]) { NSLog(@"********************************************************************************"); NSLog(@"Cedar no longer runs beforeEach blocks defined on the SpecHelper class.\n"); NSLog(@"Rather than defining a global beforeEach on the SpecHelper instance,"); NSLog(@"declare a +beforeEach class method on a separate spec-specific class."); NSLog(@"This allows for more than one beforeEach without them overwriting one another."); NSLog(@"********************************************************************************"); } [self.globalBeforeEachClasses makeObjectsPerformSelector:@selector(beforeEach)]; } - (CDRSpecBlock)subjectActionBlock { return nil; } - (void)tearDown { if ([self respondsToSelector:@selector(afterEach)]) { NSLog(@"********************************************************************************"); NSLog(@"Cedar no longer runs afterEach blocks defined on the SpecHelper class.\n"); NSLog(@"Rather than defining a global afterEach on the SpecHelper instance,"); NSLog(@"declare an +afterEach class method on a separate spec-specific class."); NSLog(@"This allows for more than one afterEach without them overwriting one another."); NSLog(@"********************************************************************************"); } [self.globalAfterEachClasses makeObjectsPerformSelector:@selector(afterEach)]; [self.sharedExampleContext removeAllObjects]; } @end ================================================ FILE: Source/CDRSpecRun.m ================================================ #import "CDRSpec.h" #import "CDRSpecRun.h" #import "CDRPrivateFunctions.h" #import "CDRReportDispatcher.h" @interface CDRSpecRun () @property (nonatomic, retain) id stateTracker; @end @implementation CDRSpecRun - (instancetype)initWithStateTracker:(id)stateTracker exampleReporters:(NSArray *)reporters { if (self = [super init]) { _stateTracker = [stateTracker retain]; [_stateTracker didStartPreparingTests]; CDRDefineSharedExampleGroups(); CDRDefineGlobalBeforeAndAfterEachBlocks(); _seed = CDRGetRandomSeed(); NSArray *specClasses = CDRSpecClassesToRun(); NSArray *permutedSpecClasses = CDRPermuteSpecClassesWithSeed(specClasses, _seed); _specs = [CDRSpecsFromSpecClasses(permutedSpecClasses) retain]; CDRMarkFocusedExamplesInSpecs(_specs); CDRMarkXcodeFocusedExamplesInSpecs(_specs, [[NSProcessInfo processInfo] arguments]); _dispatcher = [[CDRReportDispatcher alloc] initWithReporters:reporters]; _rootGroups = [[_specs valueForKey:NSStringFromSelector(@selector(rootGroup))] retain]; } return self; } - (int)performSpecRun:(void (^)(void))runBlock { [self.stateTracker didStartRunningTests]; [self.dispatcher runWillStartWithGroups:self.rootGroups andRandomSeed:self.seed]; runBlock(); [self.dispatcher runDidComplete]; [self.stateTracker didFinishRunningTests]; return [self.dispatcher result]; } #pragma mark - NSObject - (instancetype)init { [self doesNotRecognizeSelector:_cmd]; return nil; } - (void)dealloc { [_specs release]; _specs = nil; [_rootGroups release]; _rootGroups = nil; [_dispatcher release]; _dispatcher = nil; [_stateTracker release]; _stateTracker = nil; [super dealloc]; } @end ================================================ FILE: Source/CDRStateTracker.h ================================================ #import #import "CDRStateTracking.h" @interface CDRStateTracker : NSObject @end ================================================ FILE: Source/CDRStateTracker.m ================================================ #import "CDRStateTracker.h" #import "CDRRunState.h" @implementation CDRStateTracker - (void)didStartPreparingTests { CDRSetCurrentRunState(CedarRunStatePreparingTests); } - (void)didStartRunningTests { CDRSetCurrentRunState(CedarRunStateRunningTests); } - (void)didFinishRunningTests { CDRSetCurrentRunState(CedarRunStateFinished); } @end ================================================ FILE: Source/CDRStateTracking.h ================================================ #import @protocol CDRStateTracking - (void)didStartPreparingTests; - (void)didStartRunningTests; - (void)didFinishRunningTests; @end ================================================ FILE: Source/CDRSymbolicator.m ================================================ #import "CDRSymbolicator.h" #import #import #import #import const NSString *kCDRSymbolicatorErrorDomain = @"kCDRSymbolicatorErrorDomain"; const NSString *kCDRSymbolicatorErrorMessageKey = @"kCDRSymbolicatorErrorMessage"; NSUInteger CDRCallerStackAddress() { #if !CDR_SYMBOLICATION_AVAILABLE return 0; #else unw_context_t uc; if (unw_getcontext(&uc) != 0) return 0; unw_cursor_t cursor; if (unw_init_local(&cursor, &uc) != 0) return 0; NSUInteger stackAddress = 0; int depth = 2; // caller of caller of CDRCallerStackAddress while (unw_step(&cursor) > 0 && depth-- > 0) { unw_word_t ip; if (unw_get_reg(&cursor, UNW_REG_IP, &ip) != 0) return 0; stackAddress = (NSUInteger)(ip - 4); } return stackAddress; #endif } @interface CDRSymbolicator () @property (nonatomic, retain) NSMutableArray *addresses; @property (nonatomic, retain) NSMutableArray *fileNames; @property (nonatomic, retain) NSMutableArray *lineNumbers; @end @implementation CDRSymbolicator @synthesize addresses = addresses_, fileNames = fileNames_, lineNumbers = lineNumbers_; - (id)init { if (self = [super init]) { addresses_ = [[NSMutableArray alloc] init]; fileNames_ = [[NSMutableArray alloc] init]; lineNumbers_ = [[NSMutableArray alloc] init]; } return self; } - (void)dealloc { self.addresses = nil; self.fileNames = nil; self.lineNumbers = nil; [super dealloc]; } - (NSString *)fileNameForStackAddress:(NSUInteger)address { NSUInteger index = [self.addresses indexOfObject:[NSNumber numberWithUnsignedInteger:address]]; return (index == NSNotFound) ? nil : [self.fileNames objectAtIndex:index]; } - (NSUInteger)lineNumberForStackAddress:(NSUInteger)address { NSUInteger index = [self.addresses indexOfObject:[NSNumber numberWithUnsignedInteger:address]]; return (index == NSNotFound) ? 0 : [[self.lineNumbers objectAtIndex:index] unsignedIntegerValue]; } - (BOOL)symbolicateAddresses:(NSArray *)addresses error:(NSError **)error { #if !CDR_SYMBOLICATION_AVAILABLE if (error) { *error = self.buildNotAvailableError; } return NO; #else NSArray *validAddresses = [self.class validAddresses:addresses]; if (validAddresses.count == 0) { if (error) { *error = self.buildNoAddressesError; } return NO; } CDRAtosTask *atosTask = [CDRAtosTask taskForCurrentTestExecutable]; atosTask.addresses = validAddresses; [atosTask launch]; BOOL atLeastOneSuccessfulSymbolication = NO; for (int i=0; i 0) [validAddresses addObject:address]; } return validAddresses; } @end @interface CDRAtosTask () @property (retain, nonatomic) NSArray *outputLines; @end @interface CDRAtosTask (NSTaskStubs) - (void)setLaunchPath:(NSString *)path; - (void)setArguments:(NSArray *)arguments; - (void)setEnvironment:(NSDictionary *)dict; - (void)setStandardOutput:(NSPipe *)pipe; - (void)setStandardError:(NSPipe *)pipe; - (void)launch; - (void)waitUntilExit; @end @implementation CDRAtosTask @synthesize executablePath = executablePath_, slide = slide_, addresses = addresses_, outputLines = outputLines_; - (id)initWithExecutablePath:(NSString *)executablePath slide:(long)slide addresses:(NSArray *)addresses { if (self = [super init]) { self.executablePath = executablePath; self.slide = slide; self.addresses = addresses; } return self; } - (void)dealloc { self.executablePath = nil; self.addresses = nil; self.outputLines = nil; [super dealloc]; } - (void)launch { // atos must have at least one address to symbolicate // because it will otherwise wait for stdin. if (self.addresses.count == 0) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"Must provide at least one address" userInfo:nil] raise]; } NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"-o", self.executablePath, nil]; // Position-independent executables addresses need to be adjusted hence the slide argument // https://developer.apple.com/library/mac/#technotes/tn2004/tn2123.html [arguments addObject:@"-s"]; [arguments addObject:[NSString stringWithFormat:@"%lx", self.slide]]; for (NSNumber *address in self.addresses) { [arguments addObject:[NSString stringWithFormat:@"%lx", (long)address.unsignedIntegerValue]]; } // NB: this will almost always fail if the version of Xcode at this location differs from the version used to build the tests NSString *command = [DEVELOPER_BIN_DIR stringByAppendingPathComponent:@"atos"]; NSString *output = [self.class shellOutWithCommand:command arguments:arguments]; self.outputLines = [output componentsSeparatedByString:@"\n"]; } + (regex_t)lineRegex { static regex_t *rx = NULL; if (!rx) { rx = malloc(sizeof(regex_t)); regcomp(rx, "^.+\\((.+):([[:digit:]]+)\\)$", REG_EXTENDED); // __block_global_1 (in Specs) (SpecSpec2.m:12) } return *rx; // leaks rx; regfree(&rx); } - (void)valuesOnLineNumber:(NSUInteger)line fileName:(NSString **)fileName lineNumber:(NSNumber **)lineNumber { if (line >= self.outputLines.count) return; regex_t rx = [self.class lineRegex]; regmatch_t *matches = (regmatch_t *)malloc((rx.re_nsub+1) * sizeof(regmatch_t)); const char *buf = [[self.outputLines objectAtIndex:line] UTF8String]; if (regexec(&rx, buf, rx.re_nsub+1, matches, 0) == 0) { *fileName = [[[NSString alloc] initWithBytes:(buf + matches[1].rm_so) length:(NSInteger)(matches[1].rm_eo - matches[1].rm_so) encoding:NSUTF8StringEncoding] autorelease]; NSString *lineNumberStr = [[[NSString alloc] initWithBytes:(buf + matches[2].rm_so) length:(NSInteger)(matches[2].rm_eo - matches[2].rm_so) encoding:NSUTF8StringEncoding] autorelease]; *lineNumber = [NSNumber numberWithInteger:lineNumberStr.integerValue]; } free(matches); } + (NSString *)shellOutWithCommand:(NSString *)command arguments:(NSArray *)arguments { id task = [[NSClassFromString(@"NSTask") alloc] init]; // trick iOS SDK in simulator [task setEnvironment:[NSDictionary dictionary]]; [task setLaunchPath:command]; [task setArguments:arguments]; NSPipe *standardOutput = [NSPipe pipe]; // toss stderr, but suppress its output NSPipe *standardError = [NSPipe pipe]; if (standardOutput) { [task setStandardOutput:standardOutput]; [task setStandardError:standardError]; } else return nil; @try { [task launch]; } @catch (NSException *exception) { // e.g. NSInvalidArgumentException reason: 'launch path is invalid' if (exception.name == NSInvalidArgumentException) { return nil; } else @throw; } NSData *data = [[standardOutput fileHandleForReading] readDataToEndOfFile]; [task waitUntilExit]; NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; [task release]; return string; } @end @implementation CDRAtosTask (CurrentTestExecutable) + (CDRAtosTask *)taskForCurrentTestExecutable { uint32_t imageCount = _dyld_image_count(); BOOL runningWithTestBundle = objc_getClass("SenTestProbe") || objc_getClass("XCTestProbe"); for (uint32_t imageIndex = 0; imageIndex < imageCount; imageIndex++) { NSString *imageName = [NSString stringWithCString:_dyld_get_image_name(imageIndex) encoding:NSUTF8StringEncoding]; if ([imageName hasPrefix:@"/Applications/Xcode"] || [imageName hasPrefix:@"/Library/Developer"]) { continue; } if (runningWithTestBundle && ![self isImagePathATestBundle:imageName]) { continue; } long slide = _dyld_get_image_vmaddr_slide(imageIndex); return [[[self alloc] initWithExecutablePath:imageName slide:slide addresses:nil] autorelease]; } return nil; } + (BOOL)isImagePathATestBundle:(NSString *)imageName { BOOL isOCTestBundle = [imageName rangeOfString:@".octest/"].location != NSNotFound; BOOL isXCTestBundle = [imageName rangeOfString:@".xctest/"].location != NSNotFound; return isOCTestBundle || isXCTestBundle; } @end ================================================ FILE: Source/CDRTestBundleRunner.m ================================================ #import #import "CDRFunctions.h" @interface CDRTestBundleRunner : NSObject @end @implementation CDRTestBundleRunner + (void)load { if (!CDRGetTestBundleExtension()) { return; // we're not in a test bundle } CDRInjectIntoXCTestRunner(); } @end ================================================ FILE: Source/CDRTypeUtilities.m ================================================ #import "CDRTypeUtilities.h" #import "CDRNil.h" @implementation CDRTypeUtilities static NSDictionary *typeEncodingMapping; static NSDictionary *typeEncodingModifiersMapping; static NSCharacterSet *typeEncodingStringsCharacterSet; static NSCharacterSet *typeEncodingModifiersCharacterSet; + (void)initialize { BOOL longIsInt = (sizeof(int)==sizeof(long)); // See: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html typeEncodingMapping = [@{ @"c": @"char", @"i": @"int", @"s": @"short", @"l": @"long", @"q": longIsInt ? @"long long" : @"long", @"C": @"unsigned char", @"I": @"unsigned int", @"S": @"unsigned short", @"L": @"unsigned long", @"Q": longIsInt ? @"unsigned long long" : @"unsigned long", @"f": @"float", @"d": @"double", @"B": @"bool", @"v": @"void", @"*": @"char *", @"@": @"id", @"#": @"Class", @":": @"SEL", @"@?": @"", @"?": @"" } retain]; typeEncodingModifiersMapping = [@{ @"r": @"const", @"n": @"in", @"N": @"inout", @"o": @"out", @"O": @"bycopy", @"R": @"byref", @"V": @"oneway" } retain]; typeEncodingStringsCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:[[typeEncodingMapping allKeys] componentsJoinedByString:@""]] retain]; typeEncodingModifiersCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:[[typeEncodingModifiersMapping allKeys] componentsJoinedByString:@""]] retain]; } + (NSString *)typeNameForEncoding:(const char *)encodingStr { if (!encodingStr || encodingStr[0] == '\0') { return nil; } NSScanner *scanner = [NSScanner scannerWithString:[NSString stringWithUTF8String:encodingStr]]; NSInteger arraySize = 0; NSInteger pointerCount = 0; NSString *typeName = nil; NSString *modifiers = nil; if ([scanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"["] intoString:NULL]) { [scanner scanInteger:&arraySize]; } modifiers = [self scanTypeEncodingModifiersFromScanner:scanner]; NSString *pointerModifiers; if ([scanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"^"] intoString:&pointerModifiers]) { pointerCount = [pointerModifiers length]; } typeName = [self scanComplexTypeNameFromScanner:scanner]; if (!typeName) { NSString *baseEncoding; if ([scanner scanCharactersFromSet:typeEncodingStringsCharacterSet intoString:&baseEncoding]) { typeName = typeEncodingMapping[baseEncoding]; } } if (typeName) { NSMutableString *fullTypeName = [[typeName mutableCopy] autorelease]; if (modifiers) { [fullTypeName insertString:[modifiers stringByAppendingString:@" "] atIndex:0]; } for (int i=0; i 0) { [fullTypeName appendFormat:@"[%ld]", (long)arraySize]; } return fullTypeName; } else { return [NSString stringWithUTF8String:encodingStr]; } } + (NSString *)scanTypeEncodingModifiersFromScanner:(NSScanner *)scanner { NSString *modifiers = nil; if ([scanner scanCharactersFromSet:typeEncodingModifiersCharacterSet intoString:&modifiers]) { NSMutableArray *modifierNames = [NSMutableArray array]; [modifiers enumerateSubstringsInRange:NSMakeRange(0, [modifiers length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { NSString *modifierName = typeEncodingModifiersMapping[substring]; if (modifierName) { [modifierNames addObject:modifierName]; } }]; modifiers = [modifierNames count]>0 ? [modifierNames componentsJoinedByString:@" "] : nil; } return modifiers; } + (NSString *)scanComplexTypeNameFromScanner:(NSScanner *)scanner { NSString *complexTypeIntroducer; if ([scanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"{("] intoString:&complexTypeIntroducer]) { NSString *complexType = [complexTypeIntroducer isEqualToString:@"{"] ? @"struct" : @"union"; NSString *complexTypeName; [scanner scanUpToString:@"=" intoString:&complexTypeName]; if ([complexTypeName isEqualToString:@"?"]) { return [@"untagged " stringByAppendingString:complexType]; } else { return [complexType stringByAppendingFormat:@" %@", complexTypeName]; } } return nil; } + (id)boxedObjectOfBytes:(const void *)argBuffer ofObjCType:(const char *)argType { #define IS_TYPE(TYPE) (strncmp(argType, @encode(TYPE), sizeof(@encode(TYPE))) == 0) #define CONVERT_TYPE(TYPE) ({TYPE i; \ memcpy(&i, argBuffer, sizeof(TYPE)); \ i;}) if (IS_TYPE(id)) { return CONVERT_TYPE(id) ?: [CDRNil nilObject]; } else if (IS_TYPE(Class)) { return CONVERT_TYPE(Class) ?: [CDRNil nilObject]; } else if (IS_TYPE(void(^)())) { return (id)*((void **)argBuffer) ?: [CDRNil nilObject]; } else if (IS_TYPE(char *)) { BOOL isNotNull = *(char **)argBuffer != NULL; return isNotNull ? [NSString stringWithUTF8String:*(char **)argBuffer] : [CDRNil nilObject]; } else if (IS_TYPE(const char *)) { BOOL isNotNull = *(const char **)argBuffer != NULL; return isNotNull ? [NSString stringWithUTF8String:*(const char **)argBuffer] : [CDRNil nilObject]; } else if (IS_TYPE(SEL)) { return CONVERT_TYPE(SEL) ? NSStringFromSelector(CONVERT_TYPE(SEL)) : [CDRNil nilObject]; } else if (IS_TYPE(bool)) { return @(CONVERT_TYPE(bool)); } else if (IS_TYPE(char)) { return @(CONVERT_TYPE(char)); } else if (IS_TYPE(unsigned char)) { return @(CONVERT_TYPE(unsigned char)); } else if (IS_TYPE(short)) { return @(CONVERT_TYPE(short)); } else if (IS_TYPE(unsigned short)) { return @(CONVERT_TYPE(unsigned short)); } else if (IS_TYPE(int)) { return @(CONVERT_TYPE(int)); } else if (IS_TYPE(unsigned int)) { return @(CONVERT_TYPE(unsigned int)); } else if (IS_TYPE(long)) { return @(CONVERT_TYPE(long)); } else if (IS_TYPE(unsigned long)) { return @(CONVERT_TYPE(unsigned long)); } else if (IS_TYPE(unsigned long long)) { return @(CONVERT_TYPE(unsigned long long)); } else if (IS_TYPE(double)) { return @(CONVERT_TYPE(double)); } else if (IS_TYPE(float)) { return @(CONVERT_TYPE(float)); } else { return [NSValue valueWithBytes:argBuffer objCType:argType]; } #undef RETURN_IF_TYPE #undef IS_TYPE } @end ================================================ FILE: Source/Doubles/Arguments/AnyArgument.mm ================================================ #import "AnyArgument.h" namespace Cedar { namespace Doubles { namespace Arguments { const Argument::shared_ptr_t anything = Argument::shared_ptr_t(new Doubles::AnyArgument()); } }} ================================================ FILE: Source/Doubles/Arguments/AnyInstanceArgument.mm ================================================ #import "AnyInstanceArgument.h" namespace Cedar { namespace Doubles { /* virtual */ AnyInstanceArgument::~AnyInstanceArgument() {} /* virtual */ const char * const AnyInstanceArgument::value_encoding() const { return @encode(id); } /* virtual */ bool AnyInstanceArgument::matches_encoding(const char * actual_argument_encoding) const { return 0 == strncmp(actual_argument_encoding, "@", 1); } }} ================================================ FILE: Source/Doubles/Arguments/AnyInstanceConformingToProtocolArgument.mm ================================================ #import "AnyInstanceConformingToProtocolArgument.h" namespace Cedar { namespace Doubles { AnyInstanceConformingToProtocolArgument::AnyInstanceConformingToProtocolArgument(Protocol *protocol) : AnyInstanceArgument(), protocol_(protocol) {} /* virtual */ AnyInstanceConformingToProtocolArgument::~AnyInstanceConformingToProtocolArgument() {} /* virtual */ NSString * AnyInstanceConformingToProtocolArgument::value_string() const { return [NSString stringWithFormat:@"Any instance conforming to %@", NSStringFromProtocol(protocol_)]; } /* virtual */ bool AnyInstanceConformingToProtocolArgument::matches_bytes(void * actual_argument_bytes) const { return actual_argument_bytes ? [*(static_cast(actual_argument_bytes)) conformsToProtocol:protocol_] : false; } /* virtual */ bool AnyInstanceConformingToProtocolArgument::matches(const Argument &other_argument) const { const AnyInstanceConformingToProtocolArgument *other_any_instance_argument = dynamic_cast(&other_argument); if (other_any_instance_argument) { return [protocol_ isEqual:other_any_instance_argument->protocol_]; } else { return this->Argument::matches(other_argument); } } namespace Arguments { Argument::shared_ptr_t any(Protocol *protocol) { return Argument::shared_ptr_t(new AnyInstanceConformingToProtocolArgument(protocol)); } } }} ================================================ FILE: Source/Doubles/Arguments/AnyInstanceOfClassArgument.mm ================================================ #import "AnyInstanceOfClassArgument.h" namespace Cedar { namespace Doubles { AnyInstanceOfClassArgument::AnyInstanceOfClassArgument(const Class klass) : AnyInstanceArgument(), class_(klass) {} /* virtual */ AnyInstanceOfClassArgument::~AnyInstanceOfClassArgument() {} /* virtual */ NSString * AnyInstanceOfClassArgument::value_string() const { return [NSString stringWithFormat:@"Any instance of %@", class_]; } /* virtual */ bool AnyInstanceOfClassArgument::matches_bytes(void * actual_argument_bytes) const { return actual_argument_bytes ? [*(static_cast(actual_argument_bytes)) isKindOfClass:class_] : false; } /* virtual */ bool AnyInstanceOfClassArgument::matches(const Argument &other_argument) const { const AnyInstanceOfClassArgument *other_any_instance_argument = dynamic_cast(&other_argument); if (other_any_instance_argument) { return [class_ isEqual:other_any_instance_argument->class_]; } else { return this->Argument::matches(other_argument); } } namespace Arguments { Argument::shared_ptr_t any(Class klass) { return Argument::shared_ptr_t(new AnyInstanceOfClassArgument(klass)); } } }} ================================================ FILE: Source/Doubles/CDRClassFake.mm ================================================ #import "CDRFake.h" #import "CDRClassFake.h" #import "objc/runtime.h" #import "StubbedMethod.h" #import "CedarDoubleImpl.h" @interface CDRClassFake () @property (nonatomic, retain) CedarDoubleImpl *cedar_double_impl; @end @implementation CDRClassFake - (BOOL)respondsToSelector:(SEL)selector { return [self.klass instancesRespondToSelector:selector]; } - (NSString *)description { return [NSString stringWithFormat:@"Fake implementation of %@ class", self.klass]; } - (BOOL)isKindOfClass:(Class)aClass { return [self.klass isSubclassOfClass:aClass]; } - (BOOL)conformsToProtocol:(Protocol *)aProtocol { return [self.klass conformsToProtocol:aProtocol]; } - (Class)class { return self.klass; } #pragma mark - KVC Overrides - (void)setValue:(id)value forKey:(NSString *)key { [self handleKVCSelector:_cmd withValue:value forKey:key]; } - (void)setValue:(id)value forKeyPath:(NSString *)key { [self handleKVCSelector:_cmd withValue:value forKey:key]; } - (id)valueForKey:(NSString *)key { return [self handleKVCSelector:_cmd forKey:key]; } - (id)valueForKeyPath:(NSString *)key { return [self handleKVCSelector:_cmd forKey:key]; } #pragma mark - KVC Handling Implementation - (void)handleAllowedKVCSelector:(SEL)sel withValue:(id)value forKey:(NSString *)key { NSMethodSignature *signature = [self.klass methodSignatureForSelector:sel]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:sel]; [invocation setArgument:&value atIndex:2]; [invocation setArgument:&key atIndex:3]; [self forwardInvocation:invocation]; } - (void)handleKVCSelector:(SEL)sel withValue:(id)value forKey:(NSString *)key { if ([self has_stubbed_method_for:sel] || !self.requiresExplicitStubs) { [self handleAllowedKVCSelector:sel withValue:value forKey:key]; } else { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempting to set value <%@> for key <%@>, which must be stubbed first", value, key] userInfo:nil] raise]; } } - (id)handleAllowedKVCSelector:(SEL)sel forKey:(NSString *)key { NSMethodSignature *signature = [self.klass methodSignatureForSelector:sel]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; [invocation setSelector:sel]; [invocation setArgument:&key atIndex:2]; [self forwardInvocation:invocation]; __unsafe_unretained id returnValue; [invocation getReturnValue:&returnValue]; return returnValue; } - (id)handleKVCSelector:(SEL)sel forKey:(NSString *)key { if ([self has_stubbed_method_for:sel] || !self.requiresExplicitStubs) { return [self handleAllowedKVCSelector:sel forKey:key]; } else { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempting to get value for key <%@>, which must be stubbed first", key] userInfo:nil] raise]; return nil; } } @end id CDR_fake_for(BOOL require_explicit_stubs, Class klass, ...) { va_list args; va_start(args, klass); if (va_arg(args, Class)) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Can't create a fake for multiple classes." userInfo:nil] raise]; } va_end(args); return [[[CDRClassFake alloc] initWithClass:klass requireExplicitStubs:require_explicit_stubs] autorelease]; } ================================================ FILE: Source/Doubles/CDRFake.mm ================================================ #import "NSInvocation+Cedar.h" #import "CDRFake.h" #import #import "StubbedMethod.h" #import "CedarDoubleImpl.h" @interface CDRFake () @property (nonatomic, retain) CedarDoubleImpl *cedar_double_impl; @end @implementation CDRFake @synthesize klass = klass_, cedar_double_impl = cedar_double_impl_, requiresExplicitStubs = requiresExplicitStubs_; - (id)initWithClass:(Class)klass requireExplicitStubs:(BOOL)requireExplicitStubs { if (self = [super init]) { self.requiresExplicitStubs = requireExplicitStubs; self.klass = klass; self.cedar_double_impl = [[[CedarDoubleImpl alloc] initWithDouble:self] autorelease]; } return self; } - (void)dealloc { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" self.klass = nil; self.cedar_double_impl = nil; #pragma clang diagnostic pop [super dealloc]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { if ([self.cedar_double_impl has_rejected_method_for:sel]) { return nil; } return [self.klass instanceMethodSignatureForSelector:sel]; } - (void)forwardInvocation:(NSInvocation *)invocation { @try { [self.cedar_double_impl record_method_invocation:invocation]; CDRStubInvokeStatus method_invocation_result = [self.cedar_double_impl invoke_stubbed_method:invocation]; switch (method_invocation_result) { case CDRStubMethodInvoked: { // do nothing; everything's cool } break; case CDRStubMethodNotStubbed: { if (self.requiresExplicitStubs) { NSString * selectorString = NSStringFromSelector(invocation.selector); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Invocation of unstubbed method: %@", selectorString] userInfo:nil] raise]; } } break; case CDRStubWrongArguments: { if (self.requiresExplicitStubs) { NSString * reason = [NSString stringWithFormat:@"Wrong arguments supplied to stub"]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } } break; default: break; } } @finally { [invocation cdr_copyBlockArguments]; [invocation retainArguments]; } } #pragma mark - CedarDouble protocol - (Cedar::Doubles::StubbedMethod &)add_stub:(const Cedar::Doubles::StubbedMethod &)stubbed_method { return [self.cedar_double_impl add_stub:stubbed_method]; } - (void)reject_method:(const Cedar::Doubles::RejectedMethod &)rejected_method { [self.cedar_double_impl reject_method:rejected_method]; } - (NSArray *)sent_messages { return self.cedar_double_impl.sent_messages; } - (NSArray *)sent_messages_with_selector:(SEL)selector { return [self.cedar_double_impl sent_messages_with_selector:selector]; } - (void)reset_sent_messages { [self.cedar_double_impl reset_sent_messages]; } - (BOOL)can_stub:(SEL)selector { return [self.klass instancesRespondToSelector:selector] && [self.klass instanceMethodSignatureForSelector:selector]; } - (BOOL)has_stubbed_method_for:(SEL)selector { return [self.cedar_double_impl has_stubbed_method_for:selector]; } - (BOOL)has_rejected_method_for:(SEL)selector { return [self.cedar_double_impl has_rejected_method_for:selector]; } @end ================================================ FILE: Source/Doubles/CDRProtocolFake.mm ================================================ #import "CDRFake.h" #import "CDRProtocolFake.h" #import "StubbedMethod.h" #import static bool protocol_hasSelector(Protocol *protocol, SEL selector, BOOL is_required_method, BOOL is_instance_method) { objc_method_description method_description = protocol_getMethodDescription(protocol, selector, is_required_method, is_instance_method); return method_description.name && method_description.types; } static bool CDR_protocol_hasSelector(Protocol *protocol, SEL selector) { return (protocol_hasSelector(protocol, selector, true, true) || protocol_hasSelector(protocol, selector, true, false) || protocol_hasSelector(protocol, selector, false, true) || protocol_hasSelector(protocol, selector, false, false)); } @interface CDRProtocolFake () @property (retain, nonatomic) NSArray *protocols; @end @implementation CDRProtocolFake @synthesize protocols = protocols_; - (id)initWithClass:(Class)klass forProtocols:(NSArray *)protocols requireExplicitStubs:(BOOL)requireExplicitStubs; { if (self = [super initWithClass:klass requireExplicitStubs:requireExplicitStubs]) { self.protocols = protocols; } return self; } - (void)dealloc { self.protocols = nil; [super dealloc]; } - (BOOL)can_stub:(SEL)selector { if (class_respondsToSelector(self.klass, selector)) { return YES; } for (Protocol *protocol in self.protocols) { if (CDR_protocol_hasSelector(protocol, selector)) { return YES; } } return NO; } - (BOOL)respondsToSelector:(SEL)selector { if (class_respondsToSelector(self.klass, selector)) { return YES; } for (Protocol *protocol in self.protocols) { if ([self respondsToSelector:selector fromProtocol:protocol]) { return YES; } } return NO; } - (void)doesNotRecognizeSelector:(SEL)selector { if ([self has_rejected_method_for:selector]) { NSString *reason = [NSString stringWithFormat:@"Received message with explicitly rejected selector <%@>", NSStringFromSelector(selector)]; [[NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil] raise]; } [super doesNotRecognizeSelector:selector]; } - (BOOL)conformsToProtocol:(Protocol *)aProtocol { for (Protocol *protocol in self.protocols) { if (protocol_conformsToProtocol(protocol, aProtocol)) { return YES; } } return NO; } - (NSString *)description { NSMutableString *mutableDescription = [NSMutableString stringWithFormat:@"Fake implementation of %s", protocol_getName([self.protocols objectAtIndex:0])]; NSUInteger protocolCount = [self.protocols count]; for (int i = 1; i < protocolCount; i++) { [mutableDescription appendFormat:@", %s", protocol_getName([self.protocols objectAtIndex:i])]; } [mutableDescription appendString:@" protocol(s)"]; return [NSString stringWithString:mutableDescription]; } - (BOOL)respondsToSelector:(SEL)selector fromProtocol:(Protocol *)protocol { if (protocol_hasSelector(protocol, selector, true, true) || protocol_hasSelector(protocol, selector, true, false)) { return YES; } if (self.requiresExplicitStubs) { return [self has_stubbed_method_for:selector]; } else if ([self has_rejected_method_for:selector]) { return NO; } return protocol_hasSelector(protocol, selector, false, true); } @end id CDR_fake_for(BOOL require_explicit_stubs, Protocol *protocol, ...) { static size_t protocol_dummy_class_id = 0; const char *protocol_name = protocol_getName(protocol); std::stringstream class_name_emitter; class_name_emitter << "Cedar fake for <" << protocol_name; NSMutableArray *protocolArray = [NSMutableArray arrayWithObject:protocol]; va_list args; va_start(args, protocol); Protocol *p = nil; while ((p = va_arg(args, Protocol *))) { [protocolArray addObject:p]; class_name_emitter << ", " << protocol_getName(p); } va_end(args); class_name_emitter << "> #" << protocol_dummy_class_id++; Class klass = objc_allocateClassPair([CDRProtocolFake class], class_name_emitter.str().c_str(), 0); if (!klass) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Failed to create class when faking protocol %s", protocol_name] userInfo:nil] raise]; } if (!class_addProtocol(klass, @protocol(CedarDouble))) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Failed to add CedarDouble protocol class when faking protocol %s", protocol_name] userInfo:nil] raise]; } for (Protocol *proto in protocolArray) { if (!class_addProtocol(klass, proto)) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Failed to fake protocol %s, unable to add protocol to fake object", protocol_getName(proto)] userInfo:nil] raise]; } } objc_registerClassPair(klass); return [[[CDRProtocolFake alloc] initWithClass:klass forProtocols:protocolArray requireExplicitStubs:require_explicit_stubs] autorelease]; } ================================================ FILE: Source/Doubles/CDRSpy.mm ================================================ #import "NSInvocation+Cedar.h" #import "CDRSpy.h" #import #import "StubbedMethod.h" #import "CedarDoubleImpl.h" #import "CDRSpyInfo.h" @interface NSInvocation (UndocumentedPrivate) - (void)invokeUsingIMP:(IMP)imp; @end @implementation CDRSpy + (void)interceptMessagesForInstance:(id)instance { if (!instance) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Cannot spy on nil" userInfo:nil]; } if (![object_getClass(instance) conformsToProtocol:@protocol(CedarDouble)]) { [CDRSpyInfo storeSpyInfoForObject:instance]; object_setClass(instance, self); } } + (void)stopInterceptingMessagesForInstance:(id)instance { if (!instance) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Cannot stop spying on nil" userInfo:nil]; } Class originalClass = [CDRSpyInfo spyInfoForObject:instance].spiedClass; if ([CDRSpyInfo clearSpyInfoForObject:instance]) { object_setClass(instance, originalClass); } } #pragma mark - Emulating the original object - (id)retain { __block id that = self; [self as_spied_class:^{ [that retain]; }]; return self; } - (BOOL)retainWeakReference { __block id that = self; __block BOOL res = NO; [self unsafe_as_spied_class:^{ res = [that retainWeakReference]; }]; return res; } - (oneway void)release { __block id that = self; [self as_spied_class:^{ [that release]; }]; } - (id)autorelease { __block id that = self; [self as_spied_class:^{ [that autorelease]; }]; return self; } - (NSUInteger)retainCount { __block id that = self; __block NSUInteger count = 0; [self as_spied_class:^{ count = [that retainCount]; }]; return count; } - (NSString *)description { __block id that = self; __block NSString *description = nil; [self as_spied_class:^{ description = [that description]; }]; return description; } - (BOOL)isEqual:(id)object { __block id that = self; __block BOOL isEqual = NO; [self as_spied_class:^{ isEqual = [that isEqual:object]; }]; return isEqual; } - (NSUInteger)hash { __block id that = self; __block NSUInteger hash = 0; [self as_spied_class:^{ hash = [that hash]; }]; return hash; } - (Class)class { return [CDRSpyInfo publicClassForObject:self]; } - (BOOL)isKindOfClass:(Class)aClass { Class originalClass = [CDRSpyInfo publicClassForObject:self]; return [originalClass isSubclassOfClass:aClass]; } - (void)forwardInvocation:(NSInvocation *)invocation { [self.cedar_double_impl record_method_invocation:invocation]; int method_invocation_result = [self.cedar_double_impl invoke_stubbed_method:invocation]; [invocation cdr_copyBlockArguments]; [invocation retainArguments]; if (method_invocation_result != CDRStubMethodInvoked) { __block id forwardingTarget = nil; __block id that = self; SEL selector = invocation.selector; [self as_spied_class:^{ forwardingTarget = [that forwardingTargetForSelector:selector]; }]; if (forwardingTarget) { [invocation invokeWithTarget:forwardingTarget]; } else { CDRSpyInfo *spyInfo = [CDRSpyInfo spyInfoForObject:self]; IMP privateImp = [spyInfo impForSelector:selector]; if (privateImp) { [invocation invokeUsingIMP:privateImp]; } else { __block id that = self; [self as_spied_class:^{ [invocation invoke]; [spyInfo setSpiedClass:object_getClass(that)]; }]; } } } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { __block NSMethodSignature *originalMethodSignature = nil; [self as_spied_class:^{ originalMethodSignature = [self methodSignatureForSelector:sel]; }]; return originalMethodSignature; } - (BOOL)respondsToSelector:(SEL)selector { __block BOOL respondsToSelector = NO; [self as_spied_class:^{ respondsToSelector = [self respondsToSelector:selector]; }]; return respondsToSelector; } - (void)doesNotRecognizeSelector:(SEL)selector { Class originalClass = [CDRSpyInfo publicClassForObject:self]; NSString *exceptionReason = [NSString stringWithFormat:@"-[%@ %@]: unrecognized selector sent to spy %p", NSStringFromClass(originalClass), NSStringFromSelector(selector), self]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:exceptionReason userInfo:nil]; } #pragma mark - CedarDouble - (BOOL)can_stub:(SEL)selector { return [self respondsToSelector:selector] && [self methodSignatureForSelector:selector]; } - (Cedar::Doubles::StubbedMethod &)add_stub:(const Cedar::Doubles::StubbedMethod &)stubbed_method { return [self.cedar_double_impl add_stub:stubbed_method]; } - (NSArray *)sent_messages { return self.cedar_double_impl.sent_messages; } - (NSArray *)sent_messages_with_selector:(SEL)selector { return [self.cedar_double_impl sent_messages_with_selector:selector]; } - (void)reset_sent_messages { [self.cedar_double_impl reset_sent_messages]; } #pragma mark - Private - (CedarDoubleImpl *)cedar_double_impl { return [CDRSpyInfo cedarDoubleForObject:self]; } - (void)as_spied_class:(void(^)())block { CDRSpyInfo *info = [CDRSpyInfo spyInfoForObject:self]; Class originalClass = info.spiedClass; if (originalClass != Nil) { Class spyClass = object_getClass(self); object_setClass(self, originalClass); @try { block(); } @finally { if ([CDRSpyInfo spyInfoForObject:self]) { object_setClass(self, spyClass); } } } } - (void)unsafe_as_spied_class:(void(^)())block { CDRSpyInfo *info = [CDRSpyInfo spyInfoForObject:self]; Class originalClass = info.spiedClass; if (originalClass != Nil) { Class spyClass = object_getClass(self); object_setClass(self, originalClass); @try { block(); } @finally { object_setClass(self, spyClass); } } } @end ================================================ FILE: Source/Doubles/CDRSpyInfo.mm ================================================ #import "CDRSpyInfo.h" #import "CDRSpy.h" #import "CDRHooks.h" #import "CedarDoubleImpl.h" #import static NSHashTable *currentSpies__; @interface CDRSpyInfo () @property (nonatomic, assign) id originalObject; @property (nonatomic, weak) id weakOriginalObject; @end @implementation CDRSpyInfo { id _weakOriginalObject; } static char *CDRSpyKey; + (void)initialize { currentSpies__ = [[NSHashTable weakObjectsHashTable] retain]; } + (void)storeSpyInfoForObject:(id)object { CDRSpyInfo *spyInfo = [[[CDRSpyInfo alloc] init] autorelease]; spyInfo.originalObject = object; spyInfo.weakOriginalObject = object; spyInfo.publicClass = [object class]; spyInfo.spiedClass = object_getClass(object); spyInfo.cedarDouble = [[[CedarDoubleImpl alloc] initWithDouble:object] autorelease]; [currentSpies__ addObject:spyInfo]; objc_setAssociatedObject(object, &CDRSpyKey, spyInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } + (BOOL)clearSpyInfoForObject:(id)object { CDRSpyInfo *spyInfo = [CDRSpyInfo spyInfoForObject:object]; if (spyInfo) { spyInfo.originalObject = nil; spyInfo.weakOriginalObject = nil; [currentSpies__ removeObject:spyInfo]; objc_setAssociatedObject(object, &CDRSpyKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); return YES; } return NO; } - (void)dealloc { self.publicClass = nil; self.spiedClass = nil; self.originalObject = nil; self.weakOriginalObject = nil; self.cedarDouble = nil; [super dealloc]; } + (CedarDoubleImpl *)cedarDoubleForObject:(id)object { return [[self spyInfoForObject:object] cedarDouble]; } + (Class)publicClassForObject:(id)object { return [[self spyInfoForObject:object] publicClass]; } + (CDRSpyInfo *)spyInfoForObject:(id)object { return objc_getAssociatedObject(object, &CDRSpyKey); } - (IMP)impForSelector:(SEL)selector { BOOL yieldToSpiedClass = ( sel_isEqual(selector, @selector(addObserver:forKeyPath:options:context:)) || sel_isEqual(selector, @selector(didChange:valuesAtIndexes:forKey:)) || sel_isEqual(selector, @selector(mutableArrayValueForKey:)) || sel_isEqual(selector, @selector(mutableOrderedSetValueForKey:)) || sel_isEqual(selector, @selector(mutableSetValueForKey:)) || sel_isEqual(selector, @selector(removeObserver:forKeyPath:)) || sel_isEqual(selector, @selector(removeObserver:forKeyPath:context:)) || sel_isEqual(selector, @selector(setValue:forKey:)) || sel_isEqual(selector, @selector(valueForKey:)) || sel_isEqual(selector, @selector(willChange:valuesAtIndexes:forKey:)) || strcmp(class_getName(self.publicClass), class_getName(self.spiedClass)) ); if (yieldToSpiedClass) { return NULL; } Method originalMethod = class_getInstanceMethod(self.spiedClass, selector); return method_getImplementation(originalMethod); } + (void)afterEach { for (CDRSpyInfo *spyInfo in [currentSpies__ allObjects]) { id originalObject = spyInfo.weakOriginalObject; if (originalObject) { Cedar::Doubles::CDR_stop_spying_on(originalObject); } } } #pragma mark - Accessors - (id)weakOriginalObject { return objc_loadWeak(&_weakOriginalObject); } - (void)setWeakOriginalObject:(id)originalObject { objc_storeWeak(&_weakOriginalObject, originalObject); } @end ================================================ FILE: Source/Doubles/CedarDouble.mm ================================================ #import "CedarDouble.h" #import "CDRSpy.h" #import "StubbedMethod.h" #import "RejectedMethod.h" #import namespace Cedar { namespace Doubles { id operator,(id instance, const MethodStubbingMarker & marker) { Class clazz = object_getClass(instance); if (![clazz conformsToProtocol:@protocol(CedarDouble)]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ is not a double", instance] userInfo:nil] raise]; } return instance; } void operator,(id double_instance, const StubbedMethod & stubbed_method) { [double_instance add_stub:stubbed_method]; } void operator,(id double_instance, const RejectedMethod & rejected_method) { [double_instance reject_method:rejected_method]; } }} ================================================ FILE: Source/Doubles/CedarDoubleImpl.mm ================================================ #import "CedarDoubleImpl.h" #import "CDRHooks.h" using namespace Cedar::Doubles; static NSMutableArray *registeredDoubleImpls__ = nil; @interface CedarDoubleImpl () { StubbedMethod::selector_map_t stubbed_methods_; NSMutableArray *sent_messages_; NSObject *parent_double_; } @property (nonatomic, retain, readwrite) NSMutableArray *sent_messages; @property (nonatomic, retain) NSMutableArray *rejected_methods; @property (nonatomic, assign) NSObject *parent_double; @end @implementation CedarDoubleImpl @synthesize sent_messages = sent_messages_, parent_double = parent_double_; + (void)afterEach { [CedarDoubleImpl releaseRecordedInvocations]; } - (id)init { [super doesNotRecognizeSelector:_cmd]; return nil; } - (id)initWithDouble:(NSObject *)parent_double { if (self = [super init]) { self.sent_messages = [NSMutableArray array]; self.rejected_methods = [NSMutableArray array]; self.parent_double = parent_double; [CedarDoubleImpl registerDoubleImpl:self]; } return self; } - (void)dealloc { self.parent_double = nil; self.sent_messages = nil; self.rejected_methods = nil; [super dealloc]; } - (NSArray *)sent_messages_with_selector:(SEL)selector { NSMutableArray *sentMessages = [[NSMutableArray alloc] initWithCapacity:self.sent_messages.count]; for(NSInvocation *invocation in self.sent_messages) { if (invocation.selector == selector) { [sentMessages addObject:invocation]; } } return [sentMessages autorelease]; } - (void)reset_sent_messages { [self.sent_messages removeAllObjects]; } - (void)reject_method:(const RejectedMethod &)rejected_method { const SEL & selector = rejected_method.selector(); if (![self can_stub:selector]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempting to reject method <%s>, which double <%@> already does not respond to", sel_getName(selector), [self.parent_double description]] userInfo:nil] raise]; } [self.rejected_methods addObject:NSStringFromSelector(rejected_method.selector())]; } - (StubbedMethod &)add_stub:(const StubbedMethod &)stubbed_method { const SEL & selector = stubbed_method.selector(); if (![self can_stub:selector]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempting to stub method <%s>, which double <%@> does not respond to", sel_getName(selector), [self.parent_double description]] userInfo:nil] raise]; } stubbed_method.validate_against_instance(self.parent_double); if (stubbed_method.is_override()) { return [self override_stubbed_method:stubbed_method for_selector:selector]; } else { return [self insert_stubbed_method:stubbed_method for_selector:selector]; } } - (BOOL)can_stub:(SEL)selector { return [self.parent_double can_stub:selector]; } - (BOOL)has_stubbed_method_for:(SEL)selector { StubbedMethod::selector_map_t::iterator it = stubbed_methods_.find(selector); return it != stubbed_methods_.end(); } - (BOOL)has_rejected_method_for:(SEL)selector { return [self.rejected_methods containsObject:NSStringFromSelector(selector)]; } - (CDRStubInvokeStatus)invoke_stubbed_method:(NSInvocation *)invocation { StubbedMethod::selector_map_t::iterator it = stubbed_methods_.find(invocation.selector); if (it == stubbed_methods_.end()) { return CDRStubMethodNotStubbed; } StubbedMethod::stubbed_method_vector_t stubbed_methods = it->second; for (auto stubbed_method_ptr : stubbed_methods) { if (stubbed_method_ptr->matches(invocation)) { stubbed_method_ptr->invoke(invocation); return CDRStubMethodInvoked; } } return CDRStubWrongArguments; } - (void)record_method_invocation:(NSInvocation *)invocation { [self.sent_messages addObject:invocation]; } #pragma mark - Private interface + (void)releaseRecordedInvocations { [registeredDoubleImpls__ makeObjectsPerformSelector:@selector(reset_sent_messages)]; [registeredDoubleImpls__ release]; registeredDoubleImpls__ = nil; } + (void)registerDoubleImpl:(CedarDoubleImpl *)doubleImpl { if (!registeredDoubleImpls__) { registeredDoubleImpls__ = [[NSMutableArray alloc] init]; } [registeredDoubleImpls__ addObject:doubleImpl]; } - (StubbedMethod &)insert_stubbed_method:(StubbedMethod const &)stubbed_method for_selector:(SEL const &)selector { StubbedMethod::stubbed_method_vector_t &stubbed_methods = stubbed_methods_[selector]; for (auto stubbed_method_ptr : stubbed_methods) { if (stubbed_method_ptr->arguments_equal(stubbed_method)) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"The method <%s> is already stubbed with arguments (%@) - use again() to override", sel_getName(selector), stubbed_method_ptr->arguments_string()] userInfo:nil] raise]; } } StubbedMethod::shared_ptr_t stubbed_method_ptr = StubbedMethod::shared_ptr_t(new StubbedMethod(stubbed_method)); stubbed_methods.insert(stubbed_methods.begin(), stubbed_method_ptr); stable_sort(stubbed_methods.begin(), stubbed_methods.end(), [](StubbedMethod::shared_ptr_t lhs, StubbedMethod::shared_ptr_t rhs) { return lhs->arguments_specificity_ranking() > rhs->arguments_specificity_ranking(); }); return *stubbed_method_ptr; } - (StubbedMethod &)override_stubbed_method:(StubbedMethod const &)stubbed_method for_selector:(SEL const &)selector { StubbedMethod::stubbed_method_vector_t &stubbed_methods = stubbed_methods_[selector]; StubbedMethod::shared_ptr_t found_stubbed_method_ptr = nullptr; for (auto stubbed_method_ptr : stubbed_methods) { if (stubbed_method_ptr->arguments_equal(stubbed_method)) { found_stubbed_method_ptr = stubbed_method_ptr; break; } } if (found_stubbed_method_ptr == nullptr) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"The method <%s> is not stubbed with arguments (%@) - again() should only be used to override a stubbed method.", sel_getName(selector), stubbed_method.arguments_string()] userInfo:nil] raise]; } StubbedMethod::shared_ptr_t stubbed_method_ptr = StubbedMethod::shared_ptr_t(new StubbedMethod(stubbed_method)); replace(stubbed_methods.begin(), stubbed_methods.end(), found_stubbed_method_ptr, stubbed_method_ptr); return *stubbed_method_ptr; } @end ================================================ FILE: Source/Doubles/HaveReceived.mm ================================================ #import "HaveReceived.h" #import "NSInvocation+Cedar.h" namespace Cedar { namespace Doubles { NSString * recorded_invocations_message(NSArray *recordedInvocations) { NSMutableString *message = [NSMutableString string]; for (NSInvocation *invocation in recordedInvocations) { [message appendFormat:@" %@", NSStringFromSelector(invocation.selector)]; NSArray *arguments = [invocation cdr_arguments]; if (arguments.count) { [message appendFormat:@"<%@>", [arguments componentsJoinedByString:@", "]]; } [message appendString:@"\n"]; } return message; } }} ================================================ FILE: Source/Doubles/InvocationMatcher.mm ================================================ #import "InvocationMatcher.h" #import #import "CDRTypeUtilities.h" namespace Cedar { namespace Doubles { InvocationMatcher::InvocationMatcher(const SEL selector) : expectedSelector_(selector) { } void InvocationMatcher::add_argument(const Argument::shared_ptr_t argument) { arguments_.push_back(argument); } bool InvocationMatcher::matches(NSInvocation * const invocation) const { return sel_isEqual(invocation.selector, selector()) && this->matches_arguments(invocation); } void InvocationMatcher::verify_count_and_types_of_arguments(id instance) const { if (this->match_any_arguments()) { return; } NSMethodSignature *methodSignature = this->method_signature_for_instance(instance); this->compare_argument_count_to_method_signature(methodSignature); this->compare_argument_types_to_method_signature(methodSignature); } #pragma mark - Private interface bool InvocationMatcher::matches_arguments(NSInvocation * const invocation) const { bool matches = true; size_t index = OBJC_DEFAULT_ARGUMENT_COUNT; for (arguments_vector_t::const_iterator cit = arguments_.begin(); cit != arguments_.end() && matches; ++cit, ++index) { const char *actualArgumentEncoding = [invocation.methodSignature getArgumentTypeAtIndex:index]; NSUInteger actualArgumentSize; NSGetSizeAndAlignment(actualArgumentEncoding, &actualArgumentSize, nil); char actualArgumentBytes[actualArgumentSize]; [invocation getArgument:&actualArgumentBytes atIndex:index]; matches = (*cit)->matches_bytes(&actualArgumentBytes); } return matches; } NSMethodSignature *InvocationMatcher::method_signature_for_instance(id instance) const { NSMethodSignature *methodSignature = [instance methodSignatureForSelector:this->selector()]; if (!methodSignature) { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Received expectation on method <%@>, which double <%@> does not respond to", selectorString, instance] userInfo:nil] raise]; } return methodSignature; } void InvocationMatcher::compare_argument_count_to_method_signature(NSMethodSignature * const methodSignature) const { size_t actualArgumentCount = [methodSignature numberOfArguments] - OBJC_DEFAULT_ARGUMENT_COUNT; size_t expectedArgumentCount = this->arguments().size(); if (actualArgumentCount != expectedArgumentCount) { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Wrong number of expected parameters for <%@>; expected: %lu, actual: %lu", selectorString, (unsigned long)expectedArgumentCount, (unsigned long)actualArgumentCount] userInfo:nil] raise]; } } void InvocationMatcher::compare_argument_types_to_method_signature(NSMethodSignature * const methodSignature) const { size_t index = OBJC_DEFAULT_ARGUMENT_COUNT; for (arguments_vector_t::const_iterator cit = this->arguments().begin(); cit != this->arguments().end(); ++cit, ++index) { const char * actual_argument_encoding = [methodSignature getArgumentTypeAtIndex:index]; if (!(*cit)->matches_encoding(actual_argument_encoding)) { NSString * selectorString = NSStringFromSelector(this->selector()); NSString *reason = [NSString stringWithFormat:@"Attempt to compare expected argument <%@> of type '%@' with actual argument type '%@'; argument #%lu for <%@>", (*cit)->value_string(), [CDRTypeUtilities typeNameForEncoding:(*cit)->value_encoding()], [CDRTypeUtilities typeNameForEncoding:actual_argument_encoding], (unsigned long)(index - OBJC_DEFAULT_ARGUMENT_COUNT + 1), selectorString]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } } } }} ================================================ FILE: Source/Doubles/RejectedMethod.mm ================================================ #import "RejectedMethod.h" #import "AnyArgument.h" namespace Cedar { namespace Doubles { RejectedMethod::RejectedMethod(SEL selector) : InvocationMatcher(selector) {} RejectedMethod::RejectedMethod(const char * method_name) : InvocationMatcher(sel_registerName(method_name)) {} const SEL RejectedMethod::selector() const { return InvocationMatcher::selector(); } }} ================================================ FILE: Source/Doubles/StubbedMethod.mm ================================================ #import "StubbedMethod.h" #import "AnyArgument.h" #import "CDRTypeUtilities.h" #import "NSInvocation+Cedar.h" #import "NSMethodSignature+Cedar.h" #import #import namespace Cedar { namespace Doubles { StubbedMethod::StubbedMethod(SEL selector) : InvocationMatcher(selector), exception_to_raise_(0), invocation_block_(0), implementation_block_(0), is_override_(false) {} StubbedMethod::StubbedMethod(const char * method_name) : InvocationMatcher(sel_registerName(method_name)), exception_to_raise_(0), invocation_block_(0), implementation_block_(0), is_override_(false) {} StubbedMethod::StubbedMethod(const StubbedMethod &rhs) : InvocationMatcher(rhs) , return_value_(rhs.return_value_) , invocation_block_([rhs.invocation_block_ retain]) , implementation_block_([rhs.implementation_block_ retain]) , exception_to_raise_(rhs.exception_to_raise_) , is_override_(rhs.is_override_) {} /*virtual*/ StubbedMethod::~StubbedMethod() { [invocation_block_ release]; [implementation_block_ release]; } StubbedMethod & StubbedMethod::and_do(invocation_block_t block) { if (this->has_return_value()) { this->raise_for_multiple_return_values(); } else if (this->has_implementation_block()) { this->raise_for_multiple_blocks(); } invocation_block_ = [block copy]; return *this; } StubbedMethod & StubbedMethod::and_do_block(implementation_block_t block) { if (![block isKindOfClass:NSClassFromString(@"NSBlock")]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Attempted to stub and do a block that isn't a block for <%@>", NSStringFromSelector(this->selector())] userInfo:nil] raise]; } if (this->has_return_value()) { this->raise_for_multiple_return_values(); } else if (this->has_invocation_block()) { this->raise_for_multiple_blocks(); } implementation_block_ = [block copy]; return *this; } StubbedMethod & StubbedMethod::with(const Argument::shared_ptr_t argument) { this->add_argument(argument); return *this; }; StubbedMethod & StubbedMethod::and_with(const Argument::shared_ptr_t argument) { return with(argument); } StubbedMethod & StubbedMethod::again() { this->is_override_ = true; return *this; } StubbedMethod & StubbedMethod::and_raise_exception() { return and_raise_exception([NSException exceptionWithName:NSInternalInconsistencyException reason:@"Invoked a stub with exceptional behavior" userInfo:nil]); } StubbedMethod & StubbedMethod::and_raise_exception(NSObject * exception) { exception_to_raise_ = exception; return *this; } bool StubbedMethod::matches_arguments(const StubbedMethod &other_stubbed_method) const { Cedar::Doubles::InvocationMatcher::arguments_vector_t arguments = this->arguments(); Cedar::Doubles::InvocationMatcher::arguments_vector_t other_arguments = other_stubbed_method.arguments(); Cedar::Doubles::InvocationMatcher::arguments_vector_t::iterator argument_it; Cedar::Doubles::InvocationMatcher::arguments_vector_t::iterator other_argument_it; for (argument_it = arguments.begin(), other_argument_it = other_arguments.begin(); argument_it != arguments.end(); ++argument_it, ++other_argument_it) { Cedar::Doubles::Argument::shared_ptr_t argument_ptr = *argument_it; Cedar::Doubles::Argument::shared_ptr_t other_argument_ptr = *other_argument_it; if (!argument_ptr->matches(*other_argument_ptr)) { return false; } } return true; } bool StubbedMethod::arguments_equal(const StubbedMethod &other_stubbed_method) const { Cedar::Doubles::InvocationMatcher::arguments_vector_t arguments = this->arguments(); Cedar::Doubles::InvocationMatcher::arguments_vector_t other_arguments = other_stubbed_method.arguments(); auto arguments_size = std::max(arguments.size(), other_arguments.size()); arguments.resize(arguments_size, Arguments::anything); other_arguments.resize(arguments_size, Arguments::anything); for (auto argument_it = arguments.begin(), other_argument_it = other_arguments.begin(); (argument_it != arguments.end() && other_argument_it != other_arguments.end()); ++argument_it, ++other_argument_it) { Cedar::Doubles::Argument::shared_ptr_t argument_ptr = (argument_it!=arguments.end()) ? *argument_it : Arguments::anything; Cedar::Doubles::Argument::shared_ptr_t other_argument_ptr = (other_argument_it!=other_arguments.end()) ? *other_argument_it : Arguments::anything; if ((*argument_ptr) != (*other_argument_ptr)) { return false; } } return true; } unsigned int StubbedMethod::arguments_specificity_ranking() const { Cedar::Doubles::InvocationMatcher::arguments_vector_t arguments = this->arguments(); return std::accumulate(arguments.begin(), arguments.end(), 0, [](unsigned int sum, Cedar::Doubles::Argument::shared_ptr_t arg_ptr) { return sum+arg_ptr->specificity_ranking(); }); } void StubbedMethod::verify_return_value_type(id instance) const { if (this->has_return_value()) { const char * const methodReturnType = [[instance methodSignatureForSelector:this->selector()] methodReturnType]; if (!this->return_value().compatible_with_encoding(methodReturnType)) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Invalid return value type '%@' instead of '%@' for <%@>", [CDRTypeUtilities typeNameForEncoding:this->return_value().value_encoding()], [CDRTypeUtilities typeNameForEncoding:methodReturnType], NSStringFromSelector(this->selector())] userInfo:nil] raise]; } } } void StubbedMethod::verify_implementation_block_return_type(id instance) const { if (!this->has_implementation_block()) { return; } NSMethodSignature *instanceMethodSignature = [instance methodSignatureForSelector:this->selector()]; NSMethodSignature *implementationBlockMethodSignature = [NSMethodSignature cdr_signatureFromBlock:implementation_block_]; const char * const methodReturnType = [instanceMethodSignature methodReturnType]; const char * const implementationBlockReturnType = [implementationBlockMethodSignature methodReturnType]; if (0 != strcmp(implementationBlockReturnType, methodReturnType)) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Invalid return type '%@' instead of '%@' for <%@>", [CDRTypeUtilities typeNameForEncoding:implementationBlockReturnType], [CDRTypeUtilities typeNameForEncoding:methodReturnType], NSStringFromSelector(this->selector())] userInfo:nil] raise]; } } void StubbedMethod::verify_implementation_block_arguments(id instance) const { if (!this->has_implementation_block()) { return; } NSMethodSignature *instanceMethodSignature = [instance methodSignatureForSelector:this->selector()]; NSMethodSignature *implementationBlockMethodSignature = [NSMethodSignature cdr_signatureFromBlock:implementation_block_]; NSUInteger instanceMethodActualArgumentCount = [instanceMethodSignature numberOfArguments]-2; NSUInteger implementationBlockActualArgumentCount = [implementationBlockMethodSignature numberOfArguments]-1; if (instanceMethodActualArgumentCount != implementationBlockActualArgumentCount) { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Wrong number of parameters for <%@>; expected: %lu; actual: %lu (not counting the special first parameter, `id self`)", selectorString, (unsigned long)instanceMethodActualArgumentCount, (unsigned long)implementationBlockActualArgumentCount] userInfo:nil] raise]; } for (NSInteger argIndex=2, blockArgIndex=1; argIndex<[instanceMethodSignature numberOfArguments]; argIndex++, blockArgIndex++) { const char * const instanceMethodArgumentType = [instanceMethodSignature getArgumentTypeAtIndex:argIndex]; const char * const implementationBlockArgumentType = [implementationBlockMethodSignature getArgumentTypeAtIndex:blockArgIndex]; if (0 != strcmp(instanceMethodArgumentType, implementationBlockArgumentType)) { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Found argument type '%@', expected '%@'; argument #%lu for <%@>", [CDRTypeUtilities typeNameForEncoding:implementationBlockArgumentType], [CDRTypeUtilities typeNameForEncoding:instanceMethodArgumentType], (unsigned long)argIndex-1, selectorString] userInfo:nil] raise]; } } } void StubbedMethod::validate_against_instance(id instance) const { this->verify_count_and_types_of_arguments(instance); this->verify_return_value_type(instance); this->verify_implementation_block_return_type(instance); this->verify_implementation_block_arguments(instance); } NSString * StubbedMethod::arguments_string() const { NSMutableString *argumentsString = [NSMutableString string]; Cedar::Doubles::InvocationMatcher::arguments_vector_t arguments = this->arguments(); Cedar::Doubles::InvocationMatcher::arguments_vector_t::iterator argument_it; for (argument_it = arguments.begin(); argument_it != arguments.end(); ++argument_it) { [argumentsString appendFormat:@"<%@>", (*argument_it)->value_string()]; } return argumentsString; } void StubbedMethod::raise_for_multiple_return_values() const { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Multiple return values specified for <%@>", selectorString] userInfo:nil] raise]; } void StubbedMethod::raise_for_multiple_blocks() const { NSString * selectorString = NSStringFromSelector(this->selector()); [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Multiple blocks specified for <%@>", selectorString] userInfo:nil] raise]; } const SEL StubbedMethod::selector() const { return InvocationMatcher::selector(); } bool StubbedMethod::matches(NSInvocation * const invocation) const { return InvocationMatcher::matches(invocation); } bool StubbedMethod::invoke(NSInvocation * invocation) const { if (exception_to_raise_) { @throw exception_to_raise_; } else if (this->has_implementation_block()) { [invocation cdr_invokeUsingBlockWithoutSelfArgument:implementation_block_]; } else if (this->has_invocation_block()) { invocation_block_(invocation); } else if (this->has_return_value()) { const void * returnValue = this->return_value().value_bytes(); [invocation setReturnValue:const_cast(returnValue)]; return true; } return false; } }} ================================================ FILE: Source/Extensions/NSInvocation+Cedar.m ================================================ #import "NSInvocation+Cedar.h" #import "NSMethodSignature+Cedar.h" #import "CDRBlockHelper.h" #import "CDRTypeUtilities.h" #import static char COPIED_BLOCKS_KEY; @interface NSInvocation (UndocumentedPrivate) - (void)invokeUsingIMP:(IMP)imp; @end @implementation NSInvocation (Cedar) - (void)cdr_copyBlockArguments { static char *blockTypeEncoding = "@?"; NSMethodSignature *methodSignature = [self methodSignature]; NSUInteger numberOfArguments = [methodSignature numberOfArguments]; NSMutableArray *copiedBlocks = [NSMutableArray array]; for (NSUInteger argumentIndex = 2; argumentIndex < numberOfArguments; ++argumentIndex) { const char *encoding = [methodSignature getArgumentTypeAtIndex:argumentIndex]; if (strncmp(blockTypeEncoding, encoding, 2) == 0) { id argument = nil; [self getArgument:&argument atIndex:argumentIndex]; if (argument) { argument = [argument copy]; [copiedBlocks addObject:argument]; [argument release]; [self setArgument:&argument atIndex:argumentIndex]; } } } objc_setAssociatedObject(self, &COPIED_BLOCKS_KEY, copiedBlocks, OBJC_ASSOCIATION_RETAIN); } - (NSInvocation *)cdr_invocationWithoutCmdArgument { NSMethodSignature *methodSignature = [self methodSignature]; NSMethodSignature *adjustedMethodSignature = [methodSignature cdr_signatureWithoutSelectorArgument]; NSInvocation *adjustedInvocation = [NSInvocation invocationWithMethodSignature:adjustedMethodSignature]; NSInteger adjustedArgIndex = 0; for (NSInteger argIndex = 0; argIndex < [methodSignature numberOfArguments]; argIndex++) { if (argIndex == 1) { continue; } NSUInteger size; NSGetSizeAndAlignment([methodSignature getArgumentTypeAtIndex:argIndex], &size, NULL); char argBuffer[size]; [self getArgument:argBuffer atIndex:argIndex]; [adjustedInvocation setArgument:argBuffer atIndex:adjustedArgIndex]; adjustedArgIndex++; } return adjustedInvocation; } - (void)cdr_invokeUsingBlockWithoutSelfArgument:(id)block { NSInvocation *adjustedInvocation = [self cdr_invocationWithoutCmdArgument]; [adjustedInvocation setTarget:block]; struct Block_literal *blockLiteral = (struct Block_literal *)block; [adjustedInvocation invokeUsingIMP:(IMP)blockLiteral->invoke]; NSUInteger returnValueSize = [[self methodSignature] methodReturnLength]; if (returnValueSize > 0) { char returnValueBuffer[returnValueSize]; [adjustedInvocation getReturnValue:&returnValueBuffer]; [self setReturnValue:&returnValueBuffer]; } } - (NSArray *)cdr_arguments { NSMutableArray *args = [NSMutableArray array]; NSMethodSignature *methodSignature = [self methodSignature]; for (NSInteger argIndex = 2; argIndex < [methodSignature numberOfArguments]; argIndex++) { NSUInteger size; NSGetSizeAndAlignment([methodSignature getArgumentTypeAtIndex:argIndex], &size, NULL); char argBuffer[size]; memset(argBuffer, (int)sizeof(argBuffer), sizeof(char)); [self getArgument:argBuffer atIndex:argIndex]; const char *argType = [methodSignature getArgumentTypeAtIndex:argIndex]; [args addObject:[CDRTypeUtilities boxedObjectOfBytes:(const void *)argBuffer ofObjCType:argType]]; } return args; } @end ================================================ FILE: Source/Extensions/NSMethodSignature+Cedar.m ================================================ #import "NSMethodSignature+Cedar.h" #import "CDRBlockHelper.h" static const char *Block_signature(id blockObj) { struct Block_literal *block = (struct Block_literal *)blockObj; union Block_descriptor_rest descriptor_rest = block->descriptor->rest; BOOL hasCopyDispose = !!(block->flags & (1<<25)); const char *signature = hasCopyDispose ? descriptor_rest.layout_with_copy_dispose.signature : descriptor_rest.layout_without_copy_dispose.signature; return signature; } @implementation NSMethodSignature (Cedar) + (NSMethodSignature *)cdr_signatureFromBlock:(id)block { const char *signatureTypes = Block_signature(block); NSString *signatureTypesString = [NSString stringWithUTF8String:signatureTypes]; NSString *quotedSubstringsPattern = @"\".*?\""; NSString *angleBracketedSubstringsPattern = @"<.*?>"; NSString *strippedSignatureTypeString = signatureTypesString; for (NSString *pattern in @[quotedSubstringsPattern, angleBracketedSubstringsPattern]) { NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:NULL]; strippedSignatureTypeString = [regex stringByReplacingMatchesInString:strippedSignatureTypeString options:0 range:NSMakeRange(0, [strippedSignatureTypeString length]) withTemplate:@""]; } return [NSMethodSignature signatureWithObjCTypes:[strippedSignatureTypeString UTF8String]]; } - (NSMethodSignature *)cdr_signatureWithoutSelectorArgument { NSAssert([self numberOfArguments]>1 && strcmp([self getArgumentTypeAtIndex:1], ":")==0, @"Unable to remove _cmd from a method signature without a _cmd argument"); NSMutableString *modifiedTypesString = [[[NSMutableString alloc] initWithUTF8String:[self methodReturnType]] autorelease]; for (NSInteger argIndex=0; argIndex<[self numberOfArguments]; argIndex++) { if (argIndex==1) { continue; } [modifiedTypesString appendFormat:@"%s", [self getArgumentTypeAtIndex:argIndex]]; } return [NSMethodSignature signatureWithObjCTypes:[modifiedTypesString UTF8String]]; } @end ================================================ FILE: Source/Headers/Project/CDRBlockHelper.h ================================================ // See http://clang.llvm.org/docs/Block-ABI-Apple.html struct Block_literal { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor { unsigned long int reserved; unsigned long int size; union Block_descriptor_rest { struct rest_with_copy_dispose { void (*copy_helper)(void *dst, void *src); // IFF (1<<25) void (*dispose_helper)(void *src); // IFF (1<<25) const char *signature; } layout_with_copy_dispose; struct rest_without_copy_dispose { const char *signature; } layout_without_copy_dispose; } rest; } *descriptor; }; ================================================ FILE: Source/Headers/Project/CDRNil.h ================================================ #import /** * CDRNil is an internal class used to box 'nil' values when they need to be put into a * Cocoa collection. This is needed beside NSNull to allow differentiating between usages * of NSNull and true nils. */ @interface CDRNil : NSObject + (instancetype)nilObject; @end ================================================ FILE: Source/Headers/Project/CDRPrivateFunctions.h ================================================ #import #ifdef __cplusplus extern "C" { #endif void CDRMarkXcodeFocusedExamplesInSpecs(NSArray *specs, NSArray *arguments); void CDRMarkFocusedExamplesInSpecs(NSArray *specs); NSArray *CDRSpecsFromSpecClasses(NSArray *specClasses); void CDRDefineSharedExampleGroups(); void CDRDefineGlobalBeforeAndAfterEachBlocks(); unsigned int CDRGetRandomSeed(); NSArray *CDRSpecClassesToRun(); NSArray *CDRRootGroupsFromSpecs(NSArray *specs); NSArray *CDRPermuteSpecClassesWithSeed(NSArray *unsortedSpecClasses, unsigned int seed); id CDRCreateXCTestSuite(); NSBundle *CDRBundleContainingSpecs(); #ifdef __cplusplus } #endif ================================================ FILE: Source/Headers/Project/CDRRunState.h ================================================ #import typedef NS_ENUM(NSInteger, CedarRunState) { CedarRunStateNotYetStarted = 0, CedarRunStatePreparingTests = 1, CedarRunStateRunningTests = 2, CedarRunStateFinished = 3 }; OBJC_EXPORT CedarRunState CDRCurrentState(); OBJC_EXPORT void CDRSetCurrentRunState(CedarRunState); ================================================ FILE: Source/Headers/Project/CDRRuntimeUtilities.h ================================================ #import @interface CDRRuntimeUtilities : NSObject + (Class)createMixinSubclassOf:(Class)parentClass newClassName:(NSString *)newClassName templateClass:(Class)templateClass; @end ================================================ FILE: Source/Headers/Project/CDRSpecRun.h ================================================ #import #import "CDRStateTracking.h" @class CDRReportDispatcher; @interface CDRSpecRun : NSObject @property (nonatomic, retain, readonly) NSArray *specs; @property (nonatomic, retain, readonly) NSArray *rootGroups; @property (nonatomic, retain, readonly) CDRReportDispatcher *dispatcher; @property (nonatomic, assign, readonly) unsigned int seed; - (instancetype)initWithStateTracker:(id)stateTracker exampleReporters:(NSArray *)reporters; - (int)performSpecRun:(void (^)(void))runBlock; @end ================================================ FILE: Source/Headers/Project/CDRSymbolicator.h ================================================ #import #if __arm__ || TARGET_OS_WATCH // libunwind functions are not available #define CDR_SYMBOLICATION_AVAILABLE 0 #else #define CDR_SYMBOLICATION_AVAILABLE 1 #endif NSUInteger CDRCallerStackAddress(); extern NSString *kCDRSymbolicatorErrorDomain; extern NSString *kCDRSymbolicatorErrorMessageKey; typedef enum { kCDRSymbolicatorErrorNotAvailable = 100, kCDRSymbolicatorErrorNotSuccessful, kCDRSymbolicatorErrorNoAddresses, } kCDRSymbolicatorError; @interface CDRSymbolicator : NSObject - (BOOL)symbolicateAddresses:(NSArray *)addresses error:(NSError **)error; - (NSString *)fileNameForStackAddress:(NSUInteger)address; - (NSUInteger)lineNumberForStackAddress:(NSUInteger)address; @end @interface CDRAtosTask : NSObject { NSString *executablePath_; long slide_; NSArray *addresses_; NSArray *outputLines_; } @property (retain, nonatomic) NSString *executablePath; @property (assign, nonatomic) long slide; @property (retain, nonatomic) NSArray *addresses; - (id)initWithExecutablePath:(NSString *)executablePath slide:(long)slide addresses:(NSArray *)addresses; - (void)launch; - (void)valuesOnLineNumber:(NSUInteger)line fileName:(NSString **)fileName lineNumber:(NSNumber **)lineNumber; @end @interface CDRAtosTask (CurrentTestExecutable) + (CDRAtosTask *)taskForCurrentTestExecutable; @end ================================================ FILE: Source/Headers/Project/CDRTypeUtilities.h ================================================ #import @interface CDRTypeUtilities : NSObject + (NSString *)typeNameForEncoding:(const char *)encoding; + (id)boxedObjectOfBytes:(const void *)argBuffer ofObjCType:(const char *)argType; @end ================================================ FILE: Source/Headers/Project/Doubles/CDRSpyInfo.h ================================================ #import @class CedarDoubleImpl; @interface CDRSpyInfo : NSObject @property (nonatomic, assign) Class publicClass; @property (nonatomic, assign) Class spiedClass; @property (nonatomic, retain) CedarDoubleImpl *cedarDouble; + (void)storeSpyInfoForObject:(id)object; + (BOOL)clearSpyInfoForObject:(id)object; + (CDRSpyInfo *)spyInfoForObject:(id)object; + (CedarDoubleImpl *)cedarDoubleForObject:(id)object; + (Class)publicClassForObject:(id)object; - (IMP)impForSelector:(SEL)selector; @end ================================================ FILE: Source/Headers/Project/Doubles/CedarDoubleImpl.h ================================================ #import #import "CedarDouble.h" #import "StubbedMethod.h" #import "RejectedMethod.h" typedef enum { CDRStubMethodNotStubbed = 0, CDRStubMethodInvoked, CDRStubWrongArguments, } CDRStubInvokeStatus; @interface CedarDoubleImpl : NSObject + (void)afterEach; - (id)initWithDouble:(NSObject *)parent_double; - (CDRStubInvokeStatus)invoke_stubbed_method:(NSInvocation *)invocation; - (void)record_method_invocation:(NSInvocation *)invocation; @end ================================================ FILE: Source/Headers/Project/Extensions/NSInvocation+Cedar.h ================================================ #import @interface NSInvocation (Cedar) - (void)cdr_copyBlockArguments; - (void)cdr_invokeUsingBlockWithoutSelfArgument:(id)block; - (NSArray *)cdr_arguments; @end ================================================ FILE: Source/Headers/Project/Extensions/NSMethodSignature+Cedar.h ================================================ #import @interface NSMethodSignature (Cedar) + (NSMethodSignature *)cdr_signatureFromBlock:(id)block; - (NSMethodSignature *)cdr_signatureWithoutSelectorArgument; @end ================================================ FILE: Source/Headers/Project/ReporterHelpers/CDROTestNamer.h ================================================ #import @class CDRExampleBase; @interface CDROTestNamer : NSObject - (NSString *)classNameForExample:(CDRExampleBase *)example; - (NSString *)methodNameForExample:(CDRExampleBase *)example; - (NSString *)methodNameForExample:(CDRExampleBase *)example withClassName:(NSString *)className; @end ================================================ FILE: Source/Headers/Project/ReporterHelpers/CDRSlowTestStatistics.h ================================================ #import @interface CDRSlowTestStatistics : NSObject - (void)printStatsForExampleGroups:(NSArray *)groups; @end ================================================ FILE: Source/Headers/Project/Reporters/CDRReportDispatcher.h ================================================ #import "CDRExampleReporter.h" @class CDRExampleGroup, CDRExample, CDRSpec; @interface CDRReportDispatcher : NSObject { NSArray *reporters_; } + (instancetype)dispatcherWithReporters:(NSArray *)reporters; - (id)initWithReporters:(NSArray *)reporters; - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed; - (void)runDidComplete; - (int)result; - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup; - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup; - (void)runWillStartExample:(CDRExample *)example; - (void)runDidFinishExample:(CDRExample *)example; @end ================================================ FILE: Source/Headers/Project/XCTest/CDRXCTestCase.h ================================================ #import /// The methods on this class are mixed into dynamically-created XCTestCase subclasses that /// are created at runtime for each CDRSpec. @interface CDRXCTestCase : NSObject @end @interface CDRXCTestCase (InheritedFromXCTestCase) - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected; + (void)setTestInvocations:(NSArray *)array; @end ================================================ FILE: Source/Headers/Project/XCTest/CDRXCTestObserver.h ================================================ #import #import "CDRXCTestSupport.h" @interface CDRXCTestObserver : NSObject @end ================================================ FILE: Source/Headers/Project/XCTest/CDRXCTestSuite.h ================================================ #import @class CDRSpecRun; /// This class should be thought of as a XCTestSuite subclass. The methods on this class are /// copied onto a true XCTestSuite subclass created dynamically at runtime, allowing Cedar /// to not need to link with XCTest @interface CDRXCTestSuite : NSObject - (instancetype)initWithSpecRun:(CDRSpecRun *)specRun; @end ================================================ FILE: Source/Headers/Project/XCTest/CDRXCTestSupport.h ================================================ #import // This file redeclares various XCTest classes and selectors to make the compiler happy. @class XCTestSuite; @protocol XCTestObservation @optional - (void)testSuiteWillStart:(XCTestSuite *)testSuite; @end @interface CDRXCTestSupport // XCTest - (void)addTest:(id)test; - (void)performTest:(id)aRun; // XCTestSuite - (id)allTests; - (id)CDR_original_allTests; - (id)initWithName:(NSString *)aName; @end @interface XCTestObservationCenter: NSObject + (instancetype)sharedTestObservationCenter; - (void)addTestObserver:(id)observer; - (void)_addLegacyTestObserver:(id)observer; - (void)CDR_original_addTestObserver:(id)observer; - (void)CDR_original__addLegacyTestObserver:(id)observer; @end ================================================ FILE: Source/Headers/Project/XCTest/NSInvocation+CDRXExample.h ================================================ #import @class CDRReportDispatcher; @class CDRExample; @interface NSInvocation (CDRXExample) @property (nonatomic, retain, setter=cdr_setDispatcher:) CDRReportDispatcher *cdr_dispatcher; @property (nonatomic, retain, setter=cdr_setExamples:) NSArray *cdr_examples; @property (nonatomic, retain, setter=cdr_setSpecClassName:) NSString *cdr_specClassName; - (void)cdr_addSupplementaryExample:(CDRExample *)example; @end ================================================ FILE: Source/Headers/Public/CDRExample.h ================================================ #import "CDRExampleBase.h" #import "CDRNullabilityCompat.h" #import "CDRSpecFailure.h" NS_ASSUME_NONNULL_BEGIN @interface CDRExample : CDRExampleBase { CDRSpecBlock block_; CDRExampleState state_; CDRSpecFailure *failure_; } @property (nonatomic, retain, nullable) CDRSpecFailure *failure; + (id)exampleWithText:(NSString *)text andBlock:(nullable CDRSpecBlock)block; - (id)initWithText:(NSString *)text andBlock:(nullable CDRSpecBlock)block; - (BOOL)isPending; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRExampleBase.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CDRExampleParent.h" NS_ASSUME_NONNULL_BEGIN @class CDRSpec, CDRReportDispatcher; typedef NS_ENUM(NSInteger, CDRExampleState) { CDRExampleStateIncomplete = 0x00, CDRExampleStateSkipped = 0x01, CDRExampleStatePassed = 0x03, CDRExampleStatePending = 0x07, CDRExampleStateFailed = 0x0F, CDRExampleStateError = 0x1F }; @interface CDRExampleBase : NSObject { NSString *text_; NSObject *parent_; CDRSpec *spec_; BOOL focused_; NSUInteger stackAddress_; NSDate *startDate_; NSDate *endDate_; } @property (nonatomic, readonly) NSString *text; @property (nonatomic, assign, nullable) NSObject *parent; @property (nonatomic, assign, nullable) CDRSpec *spec; @property (nonatomic, assign, getter=isFocused) BOOL focused; @property (nonatomic) NSUInteger stackAddress; @property (nonatomic, readonly, nullable) NSDate *startDate; @property (nonatomic, readonly, nullable) NSDate *endDate; - (id)initWithText:(NSString *)text; - (void)runWithDispatcher:(nullable CDRReportDispatcher *)dispatcher; - (BOOL)shouldRun; - (BOOL)hasChildren; - (BOOL)hasFocusedExamples; - (NSString *)message; - (NSString *)fullText; - (NSMutableArray *)fullTextInPieces; - (NSTimeInterval)runTime; - (CDRExampleState)state; @end @interface CDRExampleBase (RunReporting) - (float)progress; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRExampleGroup.h ================================================ #import "CDRExampleBase.h" #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN @interface CDRExampleGroup : CDRExampleBase { NSMutableArray *beforeBlocks_, *examples_, *afterBlocks_; BOOL isRoot_; CDRSpecBlock subjectActionBlock_; } @property (nonatomic, copy, nullable) CDRSpecBlock subjectActionBlock; @property (nonatomic, readonly) NSArray *examples; + (id)groupWithText:(NSString *)text; - (id)initWithText:(NSString *)text isRoot:(BOOL)isRoot; - (void)add:(CDRExampleBase *)example; - (void)addBefore:(CDRSpecBlock)block; - (void)addAfter:(CDRSpecBlock)block; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRExampleParent.h ================================================ #import #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN typedef void (^CDRSpecBlock)(void); @protocol CDRExampleParent - (BOOL)shouldRun; - (void)setUp; - (nullable CDRSpecBlock)subjectActionBlock; - (void)tearDown; @optional - (BOOL)hasFullText; - (NSString *)fullText; - (NSMutableArray *)fullTextInPieces; - (NSUInteger)stackAddress; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRFunctions.h ================================================ #import #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif NSArray *CDRReportersFromEnv(const char*defaultReporterClassName); int CDRRunSpecs(); OBJC_EXPORT void CDRInjectIntoXCTestRunner(); int CDRRunSpecsWithCustomExampleReporters(NSArray *reporters); NSArray *CDRShuffleItemsInArrayWithSeed(NSArray *sortedItems, unsigned int seed); NSArray *CDRReportersToRun(); NSString *CDRGetTestBundleExtension(); void CDRSuppressStandardPipesWhileLoadingClasses(); NS_ASSUME_NONNULL_END #ifdef __cplusplus } #endif ================================================ FILE: Source/Headers/Public/CDRHooks.h ================================================ #import /** * CDRHooks * * Conform classes to this protocol if you want to register global * beforeEach and afterEach blocks that are called for all specs */ @protocol CDRHooks @optional + (void)beforeEach; + (void)afterEach; @end ================================================ FILE: Source/Headers/Public/CDRNullabilityCompat.h ================================================ #if !__has_feature(nullability) #ifndef NS_ASSUME_NONNULL_BEGIN #define NS_ASSUME_NONNULL_BEGIN #define NS_ASSUME_NONNULL_END #define nullable #define nonnull #define null_unspecified #define null_resettable #define __nullable #define __nonnull #define __null_unspecified #endif #endif ================================================ FILE: Source/Headers/Public/CDRSharedExampleGroupPool.h ================================================ #import #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN #define CDR_OVERLOADABLE __attribute__((overloadable)) @protocol CDRSharedExampleGroupPool @end /// A dictionary used to provide context for a set of shared examples. /// Using this maintains backwards-compatibility with Cedar versions which /// used a plain dictionary, while preventing the context object from being /// bridged into Swift as a Swift dictionary, which is a value type. @interface CDRSharedExampleContext: NSDictionary @end typedef void (^CDRSharedExampleGroupBlock)(CDRSharedExampleContext *); typedef void (^CDRSharedExampleContextProviderBlock)(NSMutableDictionary *); #ifdef __cplusplus extern "C" { #endif void sharedExamplesFor(NSString *, CDRSharedExampleGroupBlock); CDR_OVERLOADABLE void itShouldBehaveLike(NSString *); CDR_OVERLOADABLE void itShouldBehaveLike(NSString *, __nullable CDRSharedExampleContextProviderBlock); #ifdef __cplusplus } #endif @interface CDRSharedExampleGroupPool : NSObject @end @interface CDRSharedExampleGroupPool (SharedExampleGroupDeclaration) - (void)declareSharedExampleGroups; @end #define SHARED_EXAMPLE_GROUPS_BEGIN(name) \ @interface SharedExampleGroupPoolFor##name : CDRSharedExampleGroupPool \ @end \ @implementation SharedExampleGroupPoolFor##name \ - (void)declareSharedExampleGroups { #define SHARED_EXAMPLE_GROUPS_END \ } \ @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRSpec.h ================================================ #import #import "CDRExampleBase.h" #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN @protocol CDRExampleReporter; @class CDRExampleGroup, CDRExample, CDRSpecHelper, CDRSymbolicator; @class CDRReportDispatcher; @protocol CDRSpec @end extern const __nullable CDRSpecBlock PENDING; #ifdef __cplusplus extern "C" { #endif void beforeEach(CDRSpecBlock); void afterEach(CDRSpecBlock); void subjectAction(CDRSpecBlock); CDRExampleGroup * describe(NSString *, __nullable CDRSpecBlock); CDRExampleGroup * context(NSString *, __nullable CDRSpecBlock); CDRExample * it(NSString *, __nullable CDRSpecBlock); CDRExampleGroup * xdescribe(NSString *, __nullable CDRSpecBlock); CDRExampleGroup* xcontext(NSString *, __nullable CDRSpecBlock); CDRExample * xit(NSString *, __nullable CDRSpecBlock); CDRExampleGroup * fdescribe(NSString *, __nullable CDRSpecBlock); CDRExampleGroup * fcontext(NSString *, __nullable CDRSpecBlock); CDRExample * fit(NSString *, __nullable CDRSpecBlock); void fail(NSString *); void CDREnableSpecValidation(); void CDRDisableSpecValidation(); #ifdef __cplusplus } #endif @interface CDRSpec : NSObject { CDRExampleGroup *rootGroup_; CDRExampleGroup *currentGroup_; NSString *fileName_; CDRSymbolicator *symbolicator_; } @property (nonatomic, retain) CDRExampleGroup *currentGroup, *rootGroup; @property (nonatomic, retain, nullable) NSString *fileName; @property (nonatomic, retain) CDRSymbolicator *symbolicator; - (void)defineBehaviors; - (void)markAsFocusedClosestToLineNumber:(NSUInteger)lineNumber; - (NSArray *)allChildren; @end @interface CDRSpec (XCTestSupport) - (id)testSuiteWithRandomSeed:(unsigned int)seed dispatcher:(CDRReportDispatcher *)dispatcher; @end @interface CDRSpec (SpecDeclaration) - (void)declareBehaviors; @end #define SPEC_BEGIN(name) \ @interface name : CDRSpec \ @end \ @implementation name \ - (void)declareBehaviors { \ self.fileName = [NSString stringWithUTF8String:__FILE__]; #define SPEC_END \ } \ @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRSpecFailure.h ================================================ #import #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN @interface CDRSpecFailure : NSException { NSString *fileName_; int lineNumber_; NSArray *callStackReturnAddresses_; } @property (nonatomic, retain, readonly, nullable) NSString *fileName; @property (nonatomic, assign, readonly) int lineNumber; @property (copy, readonly, nullable) NSArray *callStackReturnAddresses; + (id)specFailureWithReason:(NSString *)reason; + (id)specFailureWithReason:(NSString *)reason fileName:(NSString *)fileName lineNumber:(int)lineNumber; + (id)specFailureWithRaisedObject:(NSObject *)object; - (id)initWithReason:(NSString *)reason; - (id)initWithReason:(NSString *)reason fileName:(NSString *)fileName lineNumber:(int)lineNumber; - (id)initWithRaisedObject:(NSObject *)object; - (nullable NSString *)callStackSymbolicatedSymbols:(NSError **)error; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/CDRSpecHelper.h ================================================ #import "CDRSpec.h" #import "CDRNullabilityCompat.h" #import "CDRHooks.h" #import "CDRSharedExampleGroupPool.h" #import "CDRExampleParent.h" #ifndef NS_SWIFT_NAME #define NS_SWIFT_NAME(_name) #endif NS_ASSUME_NONNULL_BEGIN @interface CDRSpecHelper : NSObject { NSMutableDictionary *sharedExampleContext_, *sharedExampleGroups_; NSArray *globalBeforeEachClasses_, *globalAfterEachClasses_; BOOL shouldOnlyRunFocused_; } @property (nonatomic, retain, readonly) NSMutableDictionary *sharedExampleContext; @property (nonatomic, retain) NSArray *globalBeforeEachClasses, *globalAfterEachClasses; @property (nonatomic, assign) BOOL shouldOnlyRunFocused; + (CDRSpecHelper *)specHelper NS_SWIFT_NAME(specHelper()); @end @compatibility_alias SpecHelper CDRSpecHelper; NS_ASSUME_NONNULL_END // This import is here for backwards-compatibility. // The Cedar spec template used to only import CDRSpecHelper.h #import "Cedar.h" ================================================ FILE: Source/Headers/Public/CDRVersion.h ================================================ #import static NSString *CDRVersion = @"1.0"; ================================================ FILE: Source/Headers/Public/Cedar.h ================================================ #pragma mark - Cedar Core #import "CDRVersion.h" #pragma mark - Cedar Runner #import "CDRSpec.h" #import "CDRHooks.h" #import "CDRExample.h" #import "CDRFunctions.h" #import "CDRSpecHelper.h" #import "CDRSpecFailure.h" #import "CDRExampleBase.h" #import "CDRExampleGroup.h" #import "CDRExampleParent.h" #import "CDRSharedExampleGroupPool.h" #if TARGET_OS_IPHONE && !TARGET_OS_WATCH #import "CedarApplicationDelegate.h" #import "Cedar-iOS.h" #endif #import "CedarReporters.h" #import "CedarMatchers.h" #import "CedarDoubles.h" ================================================ FILE: Source/Headers/Public/Doubles/Arguments/AnyArgument.h ================================================ #import "Argument.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { class AnyArgument : public Argument { private: AnyArgument & operator=(const AnyArgument &); public: AnyArgument() {}; virtual ~AnyArgument() {}; // Allow default copy ctor. virtual const char * const value_encoding() const { return ""; }; virtual void * value_bytes() const { return NULL; }; virtual NSString * value_string() const { return @"anything"; }; virtual bool matches_encoding(const char *) const { return true; } virtual bool matches_bytes(void *) const { return true; } virtual unsigned int specificity_ranking() const { return 0; } }; namespace Arguments { extern const Argument::shared_ptr_t anything; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/AnyInstanceArgument.h ================================================ #import "Argument.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { class AnyInstanceArgument : public Argument { public: virtual ~AnyInstanceArgument() = 0; virtual const char * const value_encoding() const; virtual void * value_bytes() const { return NULL; } virtual NSString * value_string() const = 0; virtual bool matches_encoding(const char *) const; virtual bool matches_bytes(void *) const = 0; virtual unsigned int specificity_ranking() const { return 1; } }; }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/AnyInstanceConformingToProtocolArgument.h ================================================ #import "AnyInstanceArgument.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { class AnyInstanceConformingToProtocolArgument : public AnyInstanceArgument { private: AnyInstanceConformingToProtocolArgument & operator=(const AnyInstanceConformingToProtocolArgument &); public: explicit AnyInstanceConformingToProtocolArgument(Protocol *); virtual ~AnyInstanceConformingToProtocolArgument(); // Allow default copy ctor. virtual NSString * value_string() const; virtual bool matches_bytes(void *) const; virtual bool matches(const Argument &) const; private: Protocol *protocol_; }; namespace Arguments { Argument::shared_ptr_t any(Protocol *); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/AnyInstanceOfClassArgument.h ================================================ #import "AnyInstanceArgument.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { class AnyInstanceOfClassArgument : public AnyInstanceArgument { private: AnyInstanceOfClassArgument & operator=(const AnyInstanceOfClassArgument &); public: explicit AnyInstanceOfClassArgument(const Class); virtual ~AnyInstanceOfClassArgument(); // Allow default copy ctor. virtual NSString * value_string() const; virtual bool matches_bytes(void *) const; virtual bool matches(const Argument &) const; private: const Class class_; }; namespace Arguments { Argument::shared_ptr_t any(Class); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/Argument.h ================================================ #import #ifdef __cplusplus #import #import namespace Cedar { namespace Doubles { #pragma mark - Argument class Argument { public: virtual ~Argument() = 0; virtual const char * const value_encoding() const = 0; virtual void * value_bytes() const = 0; virtual NSString * value_string() const = 0; virtual bool matches_encoding(const char *) const = 0; virtual bool matches_bytes(void *) const = 0; virtual unsigned int specificity_ranking() const = 0; typedef std::shared_ptr shared_ptr_t; virtual bool matches(const Argument &other_argument) const { return ((this->matches_encoding(other_argument.value_encoding()) && this->matches_bytes(other_argument.value_bytes())) || (other_argument.matches_encoding(this->value_encoding()) && other_argument.matches_bytes(this->value_bytes()))); } bool operator==(const Argument &other_argument) const { return typeid(*this) == typeid(other_argument) && this->matches(other_argument); } bool operator!=(const Argument &other_argument) const { return !(*this == other_argument); } }; inline /* virtual */ Argument::~Argument() {} }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/ReturnValue.h ================================================ #import "ValueArgument.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { class ReturnValue { public: virtual ~ReturnValue() = 0; virtual const char * const value_encoding() const = 0; virtual void * value_bytes() const = 0; virtual bool compatible_with_encoding(const char *) const = 0; typedef std::shared_ptr shared_ptr_t; }; inline /* virtual */ ReturnValue::~ReturnValue() {} template class TypedReturnValue : public ReturnValue { private: TypedReturnValue & operator=(const TypedReturnValue &); public: explicit TypedReturnValue(const T &); virtual ~TypedReturnValue(); virtual const char * const value_encoding() const; virtual void * value_bytes() const; virtual bool compatible_with_encoding(const char *) const; private: bool matches_encoding(const char *)const; private: const T value_; }; template TypedReturnValue::TypedReturnValue(const T & value) : value_(value) {} template /* virtual */ TypedReturnValue::~TypedReturnValue() {} template /* virtual */ const char * const TypedReturnValue::value_encoding() const { return @encode(T); } template /* virtual */ void * TypedReturnValue::value_bytes() const { return (const_cast(&value_)); } template /* virtual */ bool TypedReturnValue::compatible_with_encoding(const char * actual_argument_encoding) const { return matches_encoding(actual_argument_encoding); } template<> /* virtual */ inline bool TypedReturnValue::compatible_with_encoding(const char * actual_argument_encoding) const { return 0 == strcmp(@encode(id), actual_argument_encoding); } template<> /* virtual */ inline bool TypedReturnValue::compatible_with_encoding(const char * actual_argument_encoding) const { return (value_ == (NSInteger)nil && 0 == strcmp(@encode(id), actual_argument_encoding)) || this->matches_encoding(actual_argument_encoding); } template bool TypedReturnValue::matches_encoding(const char * actual_argument_encoding) const { return 0 == strcmp(@encode(T), actual_argument_encoding); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/Arguments/ValueArgument.h ================================================ #import "Argument.h" #import "CedarStringifiers.h" #import "CedarComparators.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { inline const char *strip_encoding_qualifiers(const char *); const char *strip_encoding_qualifiers(const char *encoding) { static const char *encoding_qualifiers = "rnNoORV"; const char *stripped = encoding; while (strchr(encoding_qualifiers, stripped[0])) { ++ stripped; } return stripped; } template class ValueArgument : public Argument { private: ValueArgument & operator=(const ValueArgument &); public: explicit ValueArgument(const T &); virtual ~ValueArgument(); // Allow default copy ctor. virtual const char * const value_encoding() const; virtual void * value_bytes() const; virtual NSString * value_string() const; virtual bool matches_encoding(const char *) const; virtual bool matches_bytes(void *) const; virtual unsigned int specificity_ranking() const; protected: bool matches_encoding_excluding_qualifiers(const char *) const; bool both_are_objects(const char *) const; bool both_are_not_objects(const char *) const; bool both_are_not_pointers(const char *) const; bool both_are_not_cstrings(const char *) const; bool both_are_not_objects_pointers_nor_cstrings(const char *) const; bool nil_argument(const char *) const; bool both_are_nil(void *) const; private: const T value_; }; template ValueArgument::ValueArgument(const T & value) : Argument(), value_(value) {} template /* virtual */ ValueArgument::~ValueArgument() {} template /* virtual */ const char * const ValueArgument::value_encoding() const { return @encode(T); } template /* virtual */ void * ValueArgument::value_bytes() const { return (const_cast(&value_)); } template /* virtual */ NSString * ValueArgument::value_string() const { return Matchers::Stringifiers::string_for(value_); } template /* virtual */ bool ValueArgument::matches_encoding(const char * actual_argument_encoding) const { return this->matches_encoding_excluding_qualifiers(actual_argument_encoding) || this->both_are_not_objects_pointers_nor_cstrings(actual_argument_encoding) || this->nil_argument(actual_argument_encoding); } template /* virtual */ bool ValueArgument::matches_bytes(void * actual_argument_bytes) const { if (actual_argument_bytes) { return (Matchers::Comparators::compare_equal(value_, *(static_cast(actual_argument_bytes))) || this->both_are_nil(actual_argument_bytes)); } else { return false; } } template /* virtual */ unsigned int ValueArgument::specificity_ranking() const { return 1000; } #pragma mark - Protected interface template bool ValueArgument::matches_encoding_excluding_qualifiers(const char * actual_argument_encoding) const { const char *encoding_excluding_qualifiers = strip_encoding_qualifiers(@encode(T)); const char *actual_argument_encoding_excluding_qualifiers = strip_encoding_qualifiers(actual_argument_encoding); if (strlen(encoding_excluding_qualifiers) == strlen(actual_argument_encoding_excluding_qualifiers)) { return 0 == strcmp(encoding_excluding_qualifiers, actual_argument_encoding_excluding_qualifiers); } return false; } template bool ValueArgument::both_are_objects(const char * actual_argument_encoding) const { return 0 == strncmp(@encode(T), "@", 1) && 0 == strncmp(actual_argument_encoding, "@", 1); } template bool ValueArgument::both_are_not_objects(const char * actual_argument_encoding) const { return 0 != strncmp(@encode(T), "@", 1) && 0 != strncmp(actual_argument_encoding, "@", 1); } template bool ValueArgument::both_are_not_pointers(const char * actual_argument_encoding) const { return 0 != strncmp(@encode(T), "^", 1) && 0 != strncmp(actual_argument_encoding, "^", 1); } template bool ValueArgument::both_are_not_cstrings(const char * actual_argument_encoding) const { return 0 != strncmp(@encode(T), "*", 1) && 0 != strncmp(actual_argument_encoding, "*", 1); } template bool ValueArgument::both_are_not_objects_pointers_nor_cstrings(const char * actual_argument_encoding) const { return this->both_are_not_objects(actual_argument_encoding) && this->both_are_not_pointers(actual_argument_encoding) && this->both_are_not_cstrings(actual_argument_encoding); } template bool ValueArgument::nil_argument(const char * actual_argument_encoding) const { void *nil_pointer = 0; return 0 == strncmp(actual_argument_encoding, "@", 1) && this->matches_bytes(&nil_pointer); } template bool ValueArgument::both_are_nil(void * actual_argument_bytes) const { return (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&value_ withObjCType:@encode(T)] nonretainedObjectValue] == nil && [[NSValue value:actual_argument_bytes withObjCType:@encode(id)] nonretainedObjectValue] == nil); } #pragma mark - CharValueArgument class CharValueArgument : public ValueArgument { public: explicit CharValueArgument(const char *value) : ValueArgument(value) {}; virtual bool matches_encoding(const char * actual_argument_encoding) const { return this->both_are_objects(actual_argument_encoding) || this->both_are_cstrings(actual_argument_encoding) || this->nil_argument(actual_argument_encoding); } private: bool both_are_cstrings(const char * actual_argument_encoding) const { return this->both_are_not_objects(actual_argument_encoding) && this->both_are_not_pointers(actual_argument_encoding) && 0 == strncmp(actual_argument_encoding, "*", 1); } }; }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/CDRClassFake.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CDRFake.h" #import "CedarDouble.h" NS_ASSUME_NONNULL_BEGIN #ifdef __cplusplus @interface CDRClassFake : CDRFake @end id CDR_fake_for(BOOL require_explicit_stubs, Class klass, ...); #endif // __cplusplus NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/Doubles/CDRFake.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CedarDouble.h" NS_ASSUME_NONNULL_BEGIN #ifdef __cplusplus @interface CDRFake : NSObject @property (nonatomic, assign) Class klass; @property (nonatomic, assign) BOOL requiresExplicitStubs; - (id)initWithClass:(Class)klass requireExplicitStubs:(BOOL)requireExplicitStubs; @end #ifndef CEDAR_DOUBLES_COMPATIBILITY_MODE #define fake_for(...) CDR_fake_for(YES, __VA_ARGS__, nil) #define nice_fake_for(...) CDR_fake_for(NO, __VA_ARGS__, nil) #endif #endif // __cplusplus NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/Doubles/CDRProtocolFake.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CedarDouble.h" #import "CDRFake.h" #ifdef __cplusplus #import #import NS_ASSUME_NONNULL_BEGIN @interface CDRProtocolFake : CDRFake - (id)initWithClass:(Class)klass forProtocols:(NSArray *)protocols requireExplicitStubs:(BOOL)requireExplicitStubs; @end id CDR_fake_for(BOOL require_explicit_stubs, Protocol *protocol, ...); NS_ASSUME_NONNULL_END #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/CDRSpy.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CedarDouble.h" NS_ASSUME_NONNULL_BEGIN #ifdef __cplusplus @interface CDRSpy : NSProxy + (void)interceptMessagesForInstance:(id)instance; + (void)stopInterceptingMessagesForInstance:(id)instance; @end namespace Cedar { namespace Doubles { inline void CDR_spy_on(id instance) { [CDRSpy interceptMessagesForInstance:instance]; } inline void CDR_stop_spying_on(id instance) { [CDRSpy stopInterceptingMessagesForInstance:instance]; } }} #ifndef CEDAR_DOUBLES_COMPATIBILITY_MODE #define spy_on(x) CDR_spy_on((x)) #define stop_spying_on(x) CDR_stop_spying_on((x)) #endif #endif // __cplusplus NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/Doubles/CedarDouble.h ================================================ #import #ifdef __cplusplus namespace Cedar { namespace Doubles { class StubbedMethod; class RejectedMethod; }} @protocol CedarDouble - (Cedar::Doubles::StubbedMethod &)add_stub:(const Cedar::Doubles::StubbedMethod &)stubbed_method; - (void)reject_method:(const Cedar::Doubles::RejectedMethod &)rejected_method; - (NSArray *)sent_messages; - (NSArray *)sent_messages_with_selector:(SEL)selector; - (void)reset_sent_messages; - (BOOL)can_stub:(SEL)selector; - (BOOL)has_stubbed_method_for:(SEL)selector; - (BOOL)has_rejected_method_for:(SEL)selector; @end namespace Cedar { namespace Doubles { struct MethodStubbingMarker { const char *fileName; int lineNumber; }; id operator,(id, const MethodStubbingMarker &); void operator,(id, const StubbedMethod &); void operator,(id, const RejectedMethod &); }} #ifndef CEDAR_MATCHERS_DISALLOW_STUB_METHOD #define stub_method(x) ,(Cedar::Doubles::MethodStubbingMarker){__FILE__, __LINE__},Cedar::Doubles::StubbedMethod((x)) #define reject_method(x) ,(Cedar::Doubles::MethodStubbingMarker){__FILE__, __LINE__},Cedar::Doubles::RejectedMethod((x)) #endif #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/CedarDoubles.h ================================================ #pragma mark - Doubles #import "CDRSpy.h" #import "CDRFake.h" #import "CDRClassFake.h" #import "CDRProtocolFake.h" #pragma mark - Matchers for Doubles #import "Argument.h" #import "ReturnValue.h" #import "AnyArgument.h" #import "HaveReceived.h" #import "ValueArgument.h" #import "StubbedMethod.h" #import "RejectedMethod.h" #import "AnyInstanceArgument.h" #import "AnyInstanceOfClassArgument.h" #import "AnyInstanceConformingToProtocolArgument.h" ================================================ FILE: Source/Headers/Public/Doubles/HaveReceived.h ================================================ #import "Base.h" #import "InvocationMatcher.h" #import "CedarDouble.h" #ifdef __cplusplus namespace Cedar { namespace Doubles { extern "C" Class object_getClass(id); extern NSString * recorded_invocations_message(NSArray *recordedInvocations); template class HaveReceived : private InvocationMatcher { private: HaveReceived & operator=(const HaveReceived &); public: explicit HaveReceived(const SEL); ~HaveReceived(); // Allow default copy ctor. template NSString * failure_message_for(const U &) const; template NSString * negative_failure_message_for(const U &) const; template HaveReceived & with(const T &); template HaveReceived & with(const T &, ArgumentPack... pack); template HaveReceived & and_with(const T & argument) { return with(argument); } bool matches(id) const; protected: template NSString * failure_message_end(const U & value, bool negation) const; private: void verify_object_is_a_double(id instance) const { Class clazz = object_getClass(instance); if (![clazz instancesRespondToSelector:@selector(sent_messages)]) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"Received expectation for non-double object <%@>", instance] userInfo:nil] raise]; } } }; inline HaveReceived<> have_received(const SEL expectedSelector) { return HaveReceived<>(expectedSelector); } inline HaveReceived<> have_received(const char * expectedMethod) { return HaveReceived<>(NSSelectorFromString([NSString stringWithUTF8String:expectedMethod])); } template<> template HaveReceived<> & HaveReceived<>::with(const T & value) { this->add_argument(value); return *this; } template template HaveReceived & HaveReceived::with(const T & value, ArgumentPack... pack) { this->with(value); this->with(pack...); return *this; } #pragma mark - Needs organization template HaveReceived::HaveReceived(const SEL expectedSelector) : InvocationMatcher(expectedSelector) { } template HaveReceived::~HaveReceived() { } template bool HaveReceived::matches(id instance) const { this->verify_object_is_a_double(instance); this->verify_count_and_types_of_arguments(instance); for (NSInvocation *invocation in [instance sent_messages]) { if (this->InvocationMatcher::matches(invocation)) { return true; } } return false; } template template NSString * HaveReceived::failure_message_for(const U & value) const { NSString * failureMessageEnd = this->failure_message_end(value, false); NSString * actualValueString = MessageBuilder_::string_for_actual_value(value); return [NSString stringWithFormat:@"Expected <%@> to %@", actualValueString, failureMessageEnd]; } template template NSString * HaveReceived::negative_failure_message_for(const U & value) const { NSString * failureMessageEnd = this->failure_message_end(value, true); NSString * actualValueString = MessageBuilder_::string_for_actual_value(value); return [NSString stringWithFormat:@"Expected <%@> to not %@", actualValueString, failureMessageEnd]; } #pragma mark - Protected interface template template NSString * HaveReceived::failure_message_end(const U & value, bool negation) const { NSString * selectorString = NSStringFromSelector(this->selector()); NSMutableString *message = [NSMutableString stringWithFormat:@"have received message <%@>", selectorString]; if (this->arguments().size()) { [message appendString:@", with arguments: <"]; arguments_vector_t::const_iterator cit = this->arguments().begin(); [message appendString:(*cit++)->value_string()]; for (; cit != this->arguments().end(); ++cit) { [message appendString:[NSString stringWithFormat:@", %@", (*cit)->value_string()]]; } [message appendString:@">"]; NSArray *recordedInvocations = [(id)value sent_messages]; if (recordedInvocations.count > 0 && !negation) { [message appendString:@" but received messages:\n"]; [message appendString:recorded_invocations_message(recordedInvocations)]; } } return message; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/InvocationMatcher.h ================================================ #import "ValueArgument.h" #ifdef __cplusplus #import namespace Cedar { namespace Doubles { class InvocationMatcher { public: typedef std::vector arguments_vector_t; enum { OBJC_DEFAULT_ARGUMENT_COUNT = 2 }; public: InvocationMatcher(const SEL); virtual ~InvocationMatcher() {} void add_argument(const Argument::shared_ptr_t argument); template void add_argument(const T &); bool matches(NSInvocation * const) const; NSString *mismatch_reason(); const SEL selector() const { return expectedSelector_; } const arguments_vector_t & arguments() const { return arguments_; } const bool match_any_arguments() const { return arguments_.empty(); } void verify_count_and_types_of_arguments(id instance) const; private: bool matches_arguments(NSInvocation * const) const; NSMethodSignature *method_signature_for_instance(id instance) const; void compare_argument_count_to_method_signature(NSMethodSignature * const methodSignature) const; void compare_argument_types_to_method_signature(NSMethodSignature * const methodSignature) const; private: const SEL expectedSelector_; arguments_vector_t arguments_; }; template void InvocationMatcher::add_argument(const T & value) { this->add_argument(Argument::shared_ptr_t(new ValueArgument(value))); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/RejectedMethod.h ================================================ #import #import "InvocationMatcher.h" #import "Argument.h" #import "ReturnValue.h" #ifdef __cplusplus #import #import namespace Cedar { namespace Doubles { class RejectedMethod : private InvocationMatcher { private: RejectedMethod & operator=(const RejectedMethod &); public: RejectedMethod(SEL); RejectedMethod(const char *); const SEL selector() const; }; }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Doubles/StubbedMethod.h ================================================ #import #import "InvocationMatcher.h" #import "Argument.h" #import "ReturnValue.h" #ifdef __cplusplus #import #import namespace Cedar { namespace Doubles { class StubbedMethod : private InvocationMatcher { private: typedef void (^invocation_block_t)(NSInvocation *); typedef id implementation_block_t; private: StubbedMethod & operator=(const StubbedMethod &); public: StubbedMethod(SEL); StubbedMethod(const char *); StubbedMethod(const StubbedMethod &); virtual ~StubbedMethod(); template StubbedMethod & and_return(const T &); StubbedMethod & and_do_block(implementation_block_t block); StubbedMethod & and_do(invocation_block_t); StubbedMethod & with(const Argument::shared_ptr_t argument); StubbedMethod & and_with(const Argument::shared_ptr_t argument); StubbedMethod & again(); template StubbedMethod & with(const T &, ArgumentPack... pack); template StubbedMethod & with(const T &); template StubbedMethod & and_with(const T &); inline StubbedMethod & with(const char *argument); StubbedMethod & and_raise_exception(); StubbedMethod & and_raise_exception(NSObject * exception); ReturnValue & return_value() const { return *return_value_; }; bool is_override() const { return is_override_; }; struct SelCompare { bool operator() (const SEL& lhs, const SEL& rhs) const { return strcmp(sel_getName(lhs), sel_getName(rhs)) < 0; } }; typedef std::shared_ptr shared_ptr_t; typedef std::vector stubbed_method_vector_t; typedef std::map selector_map_t; const SEL selector() const; bool matches_arguments(const StubbedMethod &) const; bool arguments_equal(const StubbedMethod &) const; bool matches(NSInvocation * const invocation) const; bool invoke(NSInvocation * invocation) const; void validate_against_instance(id instance) const; NSString *arguments_string() const; unsigned int arguments_specificity_ranking() const; private: bool has_return_value() const { return return_value_.get(); }; bool has_invocation_block() const { return invocation_block_; } bool has_implementation_block() const { return implementation_block_; } void verify_return_value_type(id instance) const; void verify_implementation_block_return_type(id instance) const; void verify_implementation_block_arguments(id instance) const; void raise_for_multiple_return_values() const; void raise_for_multiple_blocks() const; private: ReturnValue::shared_ptr_t return_value_; bool is_override_; invocation_block_t invocation_block_; implementation_block_t implementation_block_; NSObject * exception_to_raise_; }; template StubbedMethod & StubbedMethod::and_return(const T & return_value) { if (this->has_invocation_block()) { this->raise_for_multiple_return_values(); } else if (this->has_implementation_block()) { this->raise_for_multiple_return_values(); } return_value_ = ReturnValue::shared_ptr_t(new TypedReturnValue(return_value)); return *this; } template StubbedMethod & StubbedMethod::with(const T & argument) { return with(Argument::shared_ptr_t(new ValueArgument(argument))); } StubbedMethod & StubbedMethod::with(const char *argument) { return with(Argument::shared_ptr_t(new CharValueArgument(argument))); } template StubbedMethod & StubbedMethod::and_with(const T & argument) { return with(argument); } template StubbedMethod & StubbedMethod::with(const T & value, ArgumentPack... pack) { this->with(value); this->with(pack...); return *this; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/ActualValue.h ================================================ #import #ifdef __cplusplus #import #import "StringifiersBase.h" #import "CDRSpecFailure.h" namespace Cedar { namespace Matchers { void CDR_fail(const char *fileName, int lineNumber, NSString * reason); template class ActualValue; #pragma mark class ActualValueMatchProxy template class ActualValueMatchProxy { private: template ActualValueMatchProxy(const ActualValueMatchProxy &); template ActualValueMatchProxy & operator=(const ActualValueMatchProxy &); public: explicit ActualValueMatchProxy(const ActualValue &, bool negate = false); ActualValueMatchProxy(); template void operator()(const MatcherType &) const; ActualValueMatchProxy negate() const; private: const ActualValue & actualValue_; bool negate_; }; template ActualValueMatchProxy::ActualValueMatchProxy(const ActualValue & actualValue, bool negate /*= false */) : actualValue_(actualValue), negate_(negate) {} template template void ActualValueMatchProxy::operator()(const MatcherType & matcher) const { if (negate_) { actualValue_.execute_negative_match(matcher); } else { actualValue_.execute_positive_match(matcher); } } template ActualValueMatchProxy ActualValueMatchProxy::negate() const { return ActualValueMatchProxy(actualValue_, !negate_); } #pragma mark class ActualValue template class ActualValue { private: template ActualValue(const ActualValue &); template ActualValue & operator=(const ActualValue &); public: explicit ActualValue(const char *, int, const T &); ~ActualValue(); ActualValueMatchProxy to; ActualValueMatchProxy to_not; private: template void execute_positive_match(const MatcherType &) const; template void execute_negative_match(const MatcherType &) const; friend class ActualValueMatchProxy; private: const T & value_; std::string fileName_; int lineNumber_; }; template ActualValue::ActualValue(const char *fileName, int lineNumber, const T & value) : fileName_(fileName), lineNumber_(lineNumber), value_(value), to(*this), to_not(*this, true) { } template ActualValue::~ActualValue() { } template template void ActualValue::execute_positive_match(const MatcherType & matcher) const { if (!matcher.matches(value_)) { CDR_fail(fileName_.c_str(), lineNumber_, matcher.failure_message_for(value_)); } } template template void ActualValue::execute_negative_match(const MatcherType & matcher) const { if (matcher.matches(value_)) { CDR_fail(fileName_.c_str(), lineNumber_, matcher.negative_failure_message_for(value_)); } } template const ActualValue CDR_expect(const char *fileName, int lineNumber, const T & actualValue) { return ActualValue(fileName, lineNumber, actualValue); } inline void CDR_fail(const char *fileName, int lineNumber, NSString * reason) { [[CDRSpecFailure specFailureWithReason:reason fileName:[NSString stringWithUTF8String:fileName] lineNumber:lineNumber] raise]; } }} #ifndef CEDAR_MATCHERS_COMPATIBILITY_MODE #define expect(x) CDR_expect(__FILE__, __LINE__, (x)) #define fail(x) CDR_fail(__FILE__, __LINE__, (x)) #endif #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/Base.h ================================================ #import #ifdef __cplusplus #import #import "CedarStringifiers.h" namespace Cedar { namespace Matchers { struct BaseMessageBuilder { template static NSString * string_for_actual_value(const U & value) { return Stringifiers::string_for(value); } }; /** * Basic functionality for all matchers. Meant to be used as a convenience base class for * matcher classes. */ template class Base { private: Base & operator=(const Base &); public: Base(); virtual ~Base() = 0; // Allow default copy ctor. template NSString * failure_message_for(const U &) const; template NSString * negative_failure_message_for(const U &) const; protected: virtual NSString * failure_message_end() const = 0; }; template Base::Base() {} template Base::~Base() {} template template NSString * Base::failure_message_for(const U & value) const { NSString * failureMessageEnd = this->failure_message_end(); NSString * actualValueString = MessageBuilder_::string_for_actual_value(value); return [NSString stringWithFormat:@"Expected <%@> to %@", actualValueString, failureMessageEnd]; } template template NSString * Base::negative_failure_message_for(const U & value) const { NSString * failureMessageEnd = this->failure_message_end(); NSString * actualValueString = MessageBuilder_::string_for_actual_value(value); return [NSString stringWithFormat:@"Expected <%@> to not %@", actualValueString, failureMessageEnd]; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeCloseTo.h ================================================ #import #import "Base.h" #import "CedarComparators.h" #import "CDRSpecFailure.h" #ifdef __cplusplus #pragma mark private interface namespace Cedar { namespace Matchers { namespace Private { template class BeCloseTo : public Base<> { private: BeCloseTo & operator=(const BeCloseTo &); public: explicit BeCloseTo(const T & expectedValue); ~BeCloseTo(); // Allow default copy ctor. BeCloseTo &within(double threshold); template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: void validate_not_nil() const; private: const T & expectedValue_; double threshold_; }; template BeCloseTo::BeCloseTo(const T & expectedValue) : Base<>(), expectedValue_(expectedValue), threshold_(0.01) { } template BeCloseTo::~BeCloseTo() { } template BeCloseTo & BeCloseTo::within(double threshold) { threshold_ = threshold; return *this; } template /*virtual*/ NSString * BeCloseTo::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); NSString * thresholdString = Stringifiers::string_for(threshold_); return [NSString stringWithFormat:@"be close to <%@> (within %@)", expectedValueString, thresholdString]; } template template bool BeCloseTo::matches(const U & actualValue) const { this->validate_not_nil(); return Comparators::compare_close_to(actualValue, expectedValue_, threshold_); } template void BeCloseTo::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_close_to matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark public interface namespace Cedar { namespace Matchers { template using CedarBeCloseTo = Cedar::Matchers::Private::BeCloseTo; template CedarBeCloseTo be_close_to(const T & expectedValue) { return CedarBeCloseTo(expectedValue); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeFalsy.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class BeFalsy : public Base<> { private: BeFalsy & operator=(const BeFalsy &); public: inline BeFalsy() : Base<>() {} inline ~BeFalsy() {} // Allow default copy ctor. inline const BeFalsy & operator()() const { return *this; } template bool matches(const U &) const; protected: inline /*virtual*/ NSString * failure_message_end() const { return @"evaluate to false"; } }; static const BeFalsy be_falsy = BeFalsy(); #pragma mark Generic template bool BeFalsy::matches(const U & actualValue) const { return !actualValue; } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarBeFalsy = Cedar::Matchers::Private::BeFalsy; static const CedarBeFalsy be_falsy = CedarBeFalsy(); }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeGTE.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { template class BeGTE : public Base<> { private: BeGTE & operator=(const BeGTE &); public: explicit BeGTE(const T & expectedValue); ~BeGTE(); // Allow default copy ctor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: void validate_not_nil() const; const T & expectedValue_; }; template BeGTE::BeGTE(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template BeGTE::~BeGTE() { } template /*virtual*/ NSString * BeGTE::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); return [NSString stringWithFormat:@"be greater than or equal to <%@>", expectedValueString]; } template template bool BeGTE::matches(const U & actualValue) const { this->validate_not_nil(); return Comparators::compare_greater_than(actualValue, expectedValue_) || Comparators::compare_equal(actualValue, expectedValue_); } template void BeGTE::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_greater_than_or_equal_to matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarBeGTE = Cedar::Matchers::Private::BeGTE; template CedarBeGTE be_gte(const T & expectedValue) { return CedarBeGTE(expectedValue); } template CedarBeGTE be_greater_than_or_equal_to(const T & expectedValue) { return be_gte(expectedValue); } #pragma mark operators template bool operator>=(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to >= expectedValue; } template bool operator>=(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy(be_gte(expectedValue)); return true; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeGreaterThan.h ================================================ #import #import "Base.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Private { template class BeGreaterThan : public Base<> { private: BeGreaterThan & operator=(const BeGreaterThan &); public: explicit BeGreaterThan(const T & expectedValue); ~BeGreaterThan(); // Allow default copy ctor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: const T & expectedValue_; void validate_not_nil() const; }; template BeGreaterThan::BeGreaterThan(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template BeGreaterThan::~BeGreaterThan() { } template /*virtual*/ NSString * BeGreaterThan::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); return [NSString stringWithFormat:@"be greater than <%@>", expectedValueString]; } template template bool BeGreaterThan::matches(const U & actualValue) const { this->validate_not_nil(); return Comparators::compare_greater_than(actualValue, expectedValue_); } template void BeGreaterThan::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_greater_than matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarBeGreaterThan = Cedar::Matchers::Private::BeGreaterThan; template CedarBeGreaterThan be_greater_than(const T & expectedValue) { return CedarBeGreaterThan(expectedValue); } #pragma mark operators template bool operator>(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to > expectedValue; } template bool operator>(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy(be_greater_than(expectedValue)); return true; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeInstanceOf.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { struct BeInstanceOfMessageBuilder { template static NSString * string_for_actual_value(const U & value) { id idValue = value; return [NSString stringWithFormat:@"%@ (%@)", idValue, NSStringFromClass([idValue class])]; } }; class BeInstanceOf : public Base { private: BeInstanceOf & operator=(const BeInstanceOf &); public: explicit BeInstanceOf(const Class expectedValue); ~BeInstanceOf(); // Allow default copy ctor. template bool matches(const U &) const; BeInstanceOf & or_any_subclass(); template NSString * failure_message_for(const U &) const; protected: virtual NSString * failure_message_end() const; private: const Class expectedClass_; bool includeSubclasses_; }; inline BeInstanceOf::BeInstanceOf(const Class expectedClass) : Base(), expectedClass_(expectedClass), includeSubclasses_(false) {} inline BeInstanceOf::~BeInstanceOf() {} inline BeInstanceOf & BeInstanceOf::or_any_subclass() { includeSubclasses_ = true; return *this; } template NSString * BeInstanceOf::failure_message_for(const U & value) const { NSString *failureMessage = Base::failure_message_for(value); if ([NSStringFromClass(expectedClass_) isEqualToString:NSStringFromClass([value class])]) { failureMessage = [failureMessage stringByAppendingFormat:@". %@", @"Did you accidentally add the class to your specs target also?"]; } return failureMessage; } inline /*virtual*/ NSString * BeInstanceOf::failure_message_end() const { NSMutableString *messageEnd = [NSMutableString stringWithFormat:@"be an instance of class <%@>", expectedClass_]; if (includeSubclasses_) { [messageEnd appendString:@", or any of its subclasses"]; } return messageEnd; } #pragma mark Generic template bool BeInstanceOf::matches(const U & actualValue) const { if (includeSubclasses_) { return [actualValue isKindOfClass:expectedClass_]; } else { return [actualValue isMemberOfClass:expectedClass_]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarBeInstanceOf = Cedar::Matchers::Private::BeInstanceOf; inline CedarBeInstanceOf be_instance_of(const Class expectedValue) { return CedarBeInstanceOf(expectedValue); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeLTE.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { template class BeLTE : public Base<> { private: BeLTE & operator=(const BeLTE &); public: explicit BeLTE(const T & expectedValue); ~BeLTE(); // Allow default copy ctor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: const T & expectedValue_; void validate_not_nil() const; }; template BeLTE::BeLTE(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template BeLTE::~BeLTE() { } template /*virtual*/ NSString * BeLTE::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); return [NSString stringWithFormat:@"be less than or equal to <%@>", expectedValueString]; } template template bool BeLTE::matches(const U & actualValue) const { this->validate_not_nil(); return !Comparators::compare_greater_than(actualValue, expectedValue_); } template void BeLTE::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_less_than_or_equal_to matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarBeLTE = Cedar::Matchers::Private::BeLTE; template CedarBeLTE be_lte(const T & expectedValue) { return CedarBeLTE(expectedValue); } template CedarBeLTE be_less_than_or_equal_to(const T & expectedValue) { return be_lte(expectedValue); } #pragma mark operators template bool operator<=(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to <= expectedValue; } template bool operator<=(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy(be_lte(expectedValue)); return true; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeLessThan.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { template class BeLessThan : public Base<> { private: BeLessThan & operator=(const BeLessThan &); public: explicit BeLessThan(const T & expectedValue); ~BeLessThan(); // Allow default copy ctor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: void validate_not_nil() const; const T & expectedValue_; }; template BeLessThan::BeLessThan(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template BeLessThan::~BeLessThan() { } template /*virtual*/ NSString * BeLessThan::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); return [NSString stringWithFormat:@"be less than <%@>", expectedValueString]; } template template bool BeLessThan::matches(const U & actualValue) const { this->validate_not_nil(); return !Comparators::compare_greater_than(actualValue, expectedValue_) && !Comparators::compare_equal(actualValue, expectedValue_); } template void BeLessThan::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_less_than matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarBeLessThan = Cedar::Matchers::Private::BeLessThan; template CedarBeLessThan be_less_than(const T & expectedValue) { return CedarBeLessThan(expectedValue); } #pragma mark operators template bool operator<(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to < expectedValue; } template bool operator<(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy(be_less_than(expectedValue)); return true; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeNil.h ================================================ #import #import "Base.h" #import "CDRSpecFailure.h" #ifdef __cplusplus #include #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { struct BeNilMessageBuilder { template static NSString * string_for_actual_value(const U & value) { // ARC bug: http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html // Also blocks aren't considered a pointer type under both ARC and MRC if (strcmp(@encode(U), @encode(id)) == 0 || strcmp(@encode(U), @encode(void(^)(void))) == 0) { void *ptrOfPtr = (void *)&value; void *ptr = *(reinterpret_cast(ptrOfPtr)); return ptr ? [NSString stringWithFormat:@"%p", ptr] : @"nil"; } throw std::logic_error("Should never generate a failure message for a nil comparison to non-pointer type."); } template static NSString * string_for_actual_value(U * const & value) { return value ? [NSString stringWithFormat:@"%p", value] : @"nil"; } }; class BeNil : public Base { private: BeNil & operator=(const BeNil &); public: inline BeNil() : Base() {} inline ~BeNil() {} // Allow default copy ctor. inline const BeNil & operator()() const { return *this; } template bool matches(const U &) const; template bool matches(U * const &) const; protected: inline /*virtual*/ NSString * failure_message_end() const { return @"be nil"; } }; static const BeNil be_nil = BeNil(); #pragma mark Generic template bool BeNil::matches(const U & actualValue) const { // ARC bug: http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html // Also blocks aren't considered a pointer type under both ARC and MRC if (strcmp(@encode(U), @encode(id)) == 0 || strcmp(@encode(U), @encode(void(^)(void))) == 0) { void *ptrOfPtr = (void *)&actualValue; void *ptr = *(reinterpret_cast(ptrOfPtr)); return !ptr; } [[CDRSpecFailure specFailureWithReason:@"Attempt to compare non-pointer type to nil"] raise]; return NO; } template bool BeNil::matches(U * const & actualValue) const { return !actualValue; } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarBeNil = Cedar::Matchers::Private::BeNil; static const CedarBeNil be_nil = CedarBeNil(); }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeSameInstanceAs.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { struct BeSameInstanceAsMessageBuilder { template static NSString * string_for_actual_value(const U & value) { // ARC bug: http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html #if __has_feature(objc_arc) if (strcmp(@encode(U), @encode(id)) == 0) { void *ptrOfPtrActual = (void *)&value; const void *ptrActual = *(reinterpret_cast(ptrOfPtrActual)); return [NSString stringWithFormat:@"%p", ptrActual]; } #endif throw std::logic_error("Should never generate a failure message for a pointer comparison to non-pointer type."); } template static NSString * string_for_actual_value(U * const & value) { return value ? [NSString stringWithFormat:@"%p", value] : @"nil"; } }; template class BeSameInstanceAs : public Base { private: BeSameInstanceAs & operator=(const BeSameInstanceAs &); public: explicit BeSameInstanceAs(T * const expectedValue); ~BeSameInstanceAs(); // Allow default copy ctor. template bool matches(const U &) const; template bool matches(U * const &) const; protected: virtual NSString * failure_message_end() const; private: const T * expectedValue_; }; template BeSameInstanceAs::BeSameInstanceAs(T * const expectedValue) : Base(), expectedValue_(expectedValue) { } template BeSameInstanceAs::~BeSameInstanceAs() { } template /*virtual*/ NSString * BeSameInstanceAs::failure_message_end() const { return [NSString stringWithFormat:@"be same instance as <%p>", expectedValue_]; } #pragma mark Generic template template bool BeSameInstanceAs::matches(const U & actualValue) const { // ARC bug: http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html #if __has_feature(objc_arc) if (strcmp(@encode(U), @encode(id)) == 0) { void *ptrOfPtrActual = (void *)&actualValue; const void *ptrActual = *(reinterpret_cast(ptrOfPtrActual)); void *ptrOfPtrExpected = (void *)&expectedValue_; const void *ptrExpected = *(reinterpret_cast(ptrOfPtrExpected)); return ptrActual == ptrExpected; } #endif [[CDRSpecFailure specFailureWithReason:@"Attempt to compare non-pointer type for sameness."] raise]; return NO; } template template bool BeSameInstanceAs::matches(U * const & actualValue) const { if (actualValue == nil && expectedValue_ == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_same_instance_as matcher to check for nil. Both the actual and given values are nil. This is probably not what you intended to verify."] raise]; return NO; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcompare-distinct-pointer-types" return actualValue == expectedValue_; #pragma clang diagnostic pop } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarBeSameInstanceAs = Cedar::Matchers::Private::BeSameInstanceAs; template CedarBeSameInstanceAs be_same_instance_as(T * const expectedValue) { return CedarBeSameInstanceAs(expectedValue); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BeTruthy.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class BeTruthy : public Base<> { private: BeTruthy & operator=(const BeTruthy &); public: inline BeTruthy() : Base<>() {} inline ~BeTruthy() {} // Allow default copy ctor. inline const BeTruthy & operator()() const { return *this; } template bool matches(const U &) const; protected: inline /*virtual*/ NSString * failure_message_end() const { return @"evaluate to true"; } }; static const BeTruthy be_truthy = BeTruthy(); #pragma mark Generic template bool BeTruthy::matches(const U & actualValue) const { return !!actualValue; } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarBeTruthy = Cedar::Matchers::Private::BeTruthy; static const CedarBeTruthy be_truthy = CedarBeTruthy(); }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/BlockMatcher.h ================================================ #import "Base.h" #ifdef __cplusplus // The SDKs that ship with Xcode 7 define OBJC_BOOL_IS_BOOL or OBJC_BOOL_IS_CHAR depending // on the current platform. Here we enable backwards-compatibility #if defined(OBJC_BOOL_IS_BOOL) #define CDR_OBJC_BOOL_IS_BOOL OBJC_BOOL_IS_BOOL #elif !defined(OBJC_BOOL_IS_CHAR) && (TARGET_OS_IPHONE && __LP64__) #define CDR_OBJC_BOOL_IS_BOOL 1 #endif #if __has_feature(objc_arc) #define CDR_RELEASE(X) #else #define CDR_RELEASE(X) if (X != nil) { [X release]; } #endif namespace Cedar { namespace Matchers { typedef NSString *(^FailureMessageEndBlock)(void); #pragma mark - private interface namespace Private { template class BlockMatcher : public Base<> { private: BlockMatcher & operator=(const BlockMatcher &); public: BlockMatcher(bool (^const matchesBlock)(T subject), FailureMessageEndBlock failureMessageEndBlock); BlockMatcher(const BlockMatcher &obj); ~BlockMatcher(); bool matches(const T &) const; protected: virtual NSString * failure_message_end() const; private: bool (^const matchesBlock_)(T); const FailureMessageEndBlock failureMessageEndBlock_; }; template BlockMatcher::BlockMatcher(bool (^const matchesBlock)(T), FailureMessageEndBlock failureMessageEndBlock) : matchesBlock_([matchesBlock copy]), failureMessageEndBlock_([failureMessageEndBlock copy]) {} template BlockMatcher::BlockMatcher(const BlockMatcher &obj) : matchesBlock_([obj.matchesBlock_ copy]), failureMessageEndBlock_([obj.failureMessageEndBlock_ copy]) {} template BlockMatcher::~BlockMatcher() { CDR_RELEASE(matchesBlock_); CDR_RELEASE(failureMessageEndBlock_); } template NSString *BlockMatcher::failure_message_end() const { return failureMessageEndBlock_ ? failureMessageEndBlock_() : @""; } template bool BlockMatcher::matches(const T &subject) const { return matchesBlock_(subject); } template struct BlockMatcherBuilder { BlockMatcherBuilder(bool (^matchesBlock)(T subject)); BlockMatcherBuilder(const BlockMatcherBuilder &obj); ~BlockMatcherBuilder(); BlockMatcher matcher() const; // Explicit builder function operator BlockMatcher() const; // Implicit builder function BlockMatcherBuilder & with_failure_message_end(NSString * const message); BlockMatcherBuilder & with_failure_message_end(FailureMessageEndBlock failureMessageEndBlock); private: bool (^const matchesBlock_)(T); FailureMessageEndBlock failureMessageEndBlock_; }; template BlockMatcherBuilder::BlockMatcherBuilder(bool (^matchesBlock)(T)) : matchesBlock_([matchesBlock copy]), failureMessageEndBlock_([^{ return @"pass a test"; } copy]) {} template BlockMatcherBuilder::BlockMatcherBuilder(const BlockMatcherBuilder &obj) : matchesBlock_([obj.matchesBlock_ copy]), failureMessageEndBlock_([obj.failureMessageEndBlock_ copy]) {} template BlockMatcherBuilder::~BlockMatcherBuilder() { CDR_RELEASE(matchesBlock_); CDR_RELEASE(failureMessageEndBlock_); } template BlockMatcher BlockMatcherBuilder::matcher() const { return BlockMatcher(matchesBlock_, failureMessageEndBlock_); } template BlockMatcherBuilder::operator BlockMatcher() const { return matcher(); } template BlockMatcherBuilder & BlockMatcherBuilder::with_failure_message_end(NSString * const message) { return with_failure_message_end(^{ return message; }); } template BlockMatcherBuilder & BlockMatcherBuilder::with_failure_message_end(FailureMessageEndBlock failureMessageEndBlock) { CDR_RELEASE(failureMessageEndBlock_); failureMessageEndBlock_ = [failureMessageEndBlock copy]; return *this; } } #pragma mark - public interface template using CedarBlockMatcher = Cedar::Matchers::Private::BlockMatcher; template using CedarBlockMatcherBuilder = Cedar::Matchers::Private::BlockMatcherBuilder; template CedarBlockMatcherBuilder expectationVerifier(bool (^matchesBlock)(T subject)) { return CedarBlockMatcherBuilder(matchesBlock); } template CedarBlockMatcher matcherFor(NSString * const failureMessageEnd, bool (^matchesBlock)(T subject)) { return expectationVerifier(matchesBlock).with_failure_message_end(failureMessageEnd); } #if !CDR_OBJC_BOOL_IS_BOOL template CedarBlockMatcherBuilder expectationVerifier(BOOL (^matchesBlock)(T subject)) { return CedarBlockMatcherBuilder(^(T subject){ return !(matchesBlock(subject) == NO); }); } template CedarBlockMatcher matcherFor(NSString * const failureMessageEnd, BOOL (^matchesBlock)(T subject)) { return expectationVerifier(matchesBlock).with_failure_message_end(failureMessageEnd); } #endif }} #undef CDR_RELEASE #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/ConformTo.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class ConformTo : public Base<> { private: ConformTo & operator=(const ConformTo &); public: explicit ConformTo(const char *); ConformTo(Protocol *protocol); ~ConformTo(); // Allow default copy ctor. bool matches(const id) const; protected: virtual NSString * failure_message_end() const; private: const char *expectedProtocolName_; }; }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarConformTo = Cedar::Matchers::Private::ConformTo; inline CedarConformTo conform_to(Protocol *protocol) { return CedarConformTo(protocol); } inline CedarConformTo conform_to(const char *protocolName) { return CedarConformTo(protocolName); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/Equal.h ================================================ #import #import "Base.h" #import "ComparatorsBase.h" #ifdef __cplusplus #pragma mark - Private interface namespace Cedar { namespace Matchers { namespace Private { template class Equal : public Base<> { private: Equal & operator=(const Equal &); public: explicit Equal(const T & expectedValue); ~Equal(); // Allow default copy ctor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: void validate_not_nil() const; private: const T & expectedValue_; }; template Equal::Equal(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template Equal::~Equal() { } template /*virtual*/ NSString * Equal::failure_message_end() const { NSString * expectedValueString = Stringifiers::string_for(expectedValue_); return [NSString stringWithFormat:@"equal <%@>", expectedValueString]; } template template bool Equal::matches(const U & actualValue) const { this->validate_not_nil(); return Comparators::compare_equal(actualValue, expectedValue_); } template void Equal::validate_not_nil() const { if (0 == strncmp(@encode(T), "@", 1) && [[NSValue value:&expectedValue_ withObjCType:@encode(T)] nonretainedObjectValue] == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values"] raise]; } } }}} #pragma mark - Public interface namespace Cedar { namespace Matchers { template using CedarEqual = Cedar::Matchers::Private::Equal; template CedarEqual equal(const T &expectedValue) { return CedarEqual(expectedValue); } #pragma mark equality operators template bool operator==(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to == expectedValue; } template bool operator==(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy(equal(expectedValue)); return true; } template bool operator!=(const ActualValue & actualValue, const U & expectedValue) { return actualValue.to != expectedValue; } template bool operator!=(const ActualValueMatchProxy & actualValueMatchProxy, const U & expectedValue) { actualValueMatchProxy.negate()(equal(expectedValue)); return true; } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/Exist.h ================================================ #import #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class Exist : public Base<> { public: virtual NSString * failure_message_end() const { return @"exist on the local filesystem"; } template bool matches(T * const &) const; bool matches(NSString * const path) const { return [[NSFileManager defaultManager] fileExistsAtPath:path]; } bool matches(NSURL * const URL) const { return matches([URL path]); } }; }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarExist = Cedar::Matchers::Private::Exist; static const CedarExist exist = CedarExist(); }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/RaiseException.h ================================================ #import "Base.h" #ifdef __cplusplus #import #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { typedef void (^empty_block_t)(); struct RaiseExceptionMessageBuilder { static NSString * string_for_actual_value(empty_block_t value) { return [value description]; } }; class RaiseException : public Base { private: RaiseException & operator=(const RaiseException &); public: explicit RaiseException(NSObject * = nil, Class = nil, bool = false, NSString * = nil, NSString * = nil); ~RaiseException(); // Allow default copy ctor. RaiseException operator()() const; RaiseException operator()(Class) const; RaiseException operator()(NSObject *) const; RaiseException & or_subclass(); RaiseException & with_reason(NSString * const reason); RaiseException with_reason(NSString * const reason) const; RaiseException & with_name(NSString * const name); RaiseException with_name(NSString * const name) const; bool matches(empty_block_t) const; protected: virtual NSString * failure_message_end() const; private: bool exception_matches_expected_class(NSObject * const exception) const; bool exception_matches_expected_instance(NSObject * const exception) const; bool exception_matches_expected_reason(NSObject * const exception) const; bool exception_matches_expected_name(NSObject * const exception) const; private: const NSObject *expectedExceptionInstance_; const Class expectedExceptionClass_; bool allowSubclasses_; NSString *expectedReason_; NSString *expectedName_; }; }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarRaiseException = Cedar::Matchers::Private::RaiseException; static const CedarRaiseException raise_exception; }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Base/RespondTo.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class RespondTo : public Base<> { private: RespondTo & operator=(const RespondTo &); public: explicit RespondTo(const char *); RespondTo(SEL selector); ~RespondTo(); // Allow default copy ctor. bool matches(const id) const; protected: virtual NSString * failure_message_end() const; private: const char *expectedSelectorName_; }; }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarRespondTo = Cedar::Matchers::Private::RespondTo; inline CedarRespondTo respond_to(const SEL selector) { return CedarRespondTo(selector); } inline CedarRespondTo respond_to(const char *selectorName) { return CedarRespondTo(selectorName); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/CedarComparators.h ================================================ #import "ComparatorsBase.h" #import "ComparatorsContainer.h" #if TARGET_OS_IPHONE && !TARGET_OS_WATCH #import "UIKitComparatorsContainer.h" #endif #import "ComparatorsContainerConvenience.h" #ifdef CEDAR_CUSTOM_COMPARATORS #import CEDAR_CUSTOM_COMPARATORS #endif ================================================ FILE: Source/Headers/Public/Matchers/CedarMatchers.h ================================================ #import "CedarStringifiers.h" #import "CedarComparators.h" #pragma mark - Base #import "Base.h" #import "ActualValue.h" #import "ShouldSyntax.h" #pragma mark - Matchers #import "Equal.h" #import "BeTruthy.h" #import "BeFalsy.h" #import "BeNil.h" #import "BeCloseTo.h" #import "BeSameInstanceAs.h" #import "BeInstanceOf.h" #import "BeGreaterThan.h" #import "BeGTE.h" #import "BeLessThan.h" #import "BeLTE.h" #import "RaiseException.h" #import "RespondTo.h" #import "ConformTo.h" #import "BlockMatcher.h" #pragma mark - Container #import "BeEmpty.h" #import "AnInstanceOf.h" #import "Contain.h" #import "ContainSubset.h" #pragma mark - Verifiers #import "Exist.h" #ifdef __cplusplus #ifdef CEDAR_CUSTOM_MATCHERS #import CEDAR_CUSTOM_MATCHERS #endif #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/CedarStringifiers.h ================================================ #import "StringifiersBase.h" #import "StringifiersContainer.h" #if TARGET_OS_MAC #if TARGET_OS_IPHONE #import "UIGeometryStringifiers.h" #else #import "OSXGeometryStringifiers.h" #endif #endif #ifdef CEDAR_CUSTOM_STRINGIFIERS #import CEDAR_CUSTOM_STRINGIFIERS #endif ================================================ FILE: Source/Headers/Public/Matchers/Comparators/AnInstanceOf.h ================================================ #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class AnInstanceOf { private: AnInstanceOf & operator=(const AnInstanceOf &); public: explicit AnInstanceOf(const Class); virtual ~AnInstanceOf(); // Allow default copy ctor. AnInstanceOf & or_any_subclass(); NSString * expected_class_string() const; template bool matches(const U &, Comparators::contains_options) const; private: const Class class_; bool includesSubclasses_; }; inline AnInstanceOf::AnInstanceOf(const Class klass) : class_(klass), includesSubclasses_(false) { } inline /* virtual */ AnInstanceOf::~AnInstanceOf() { } inline AnInstanceOf & AnInstanceOf::or_any_subclass() { includesSubclasses_ = true; return *this; } inline NSString * AnInstanceOf::expected_class_string() const { return [NSString stringWithFormat:@"an instance of %@%@", Stringifiers::string_for(class_), includesSubclasses_ ? @" or any subclass" : @""]; } #pragma mark - Matches template bool AnInstanceOf::matches(const U & container, Comparators::contains_options options) const { return Comparators::compare_contains(container, class_, options, includesSubclasses_ ? [](id lhs, Class rhs) { return [lhs isKindOfClass:rhs]; } : [](id lhs, Class rhs) { return [lhs isMemberOfClass:rhs]; }); } #pragma mark Matches Strings template<> inline bool AnInstanceOf::matches(char * const & container, Comparators::contains_options options) const { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of 'contain' matcher to check for an object in a string" userInfo:nil] raise]; return false; } template<> inline bool AnInstanceOf::matches(const char * const & container, Comparators::contains_options options) const { return matches((char *)container, options); } template<> inline bool AnInstanceOf::matches(NSString * const & container, Comparators::contains_options options) const { return matches((char *)nil, options); } template<> inline bool AnInstanceOf::matches(NSMutableString * const & container, Comparators::contains_options options) const { return matches((char *)nil, options); } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarAnInstanceOf = Cedar::Matchers::Private::AnInstanceOf; inline CedarAnInstanceOf an_instance_of(Class klass) { return CedarAnInstanceOf(klass); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Comparators/ComparatorsBase.h ================================================ #import "CompareEqual.h" #import "CompareGreaterThan.h" #import "CompareCloseTo.h" #if TARGET_OS_MAC #if TARGET_OS_IPHONE #import "UIGeometryCompareEqual.h" #else #import "OSXGeometryCompareEqual.h" #endif #endif ================================================ FILE: Source/Headers/Public/Matchers/Comparators/ComparatorsContainer.h ================================================ #ifdef __cplusplus #import #import #import #import // Container namespace Cedar { namespace Matchers { namespace Comparators { #pragma mark - compare_empty template bool compare_empty(const T & container) { if (container == nil) { [[CDRSpecFailure specFailureWithReason:@"Unexpected use of be_empty matcher to check for nil. The actual value was nil. This is probably not what you intended to verify."] raise]; return false; } if ([container respondsToSelector:@selector(count)]) { return 0 == [container performSelector:@selector(count)]; } else { return 0 == [container performSelector:@selector(length)]; } } template bool compare_empty(const typename std::vector & container) { return container.empty(); } template bool compare_empty(const typename std::map & container) { return container.empty(); } template bool compare_empty(const typename std::set & container) { return container.empty(); } #pragma mark - compare_contains typedef struct { bool nested:1; bool as_key:1; bool as_value:1; } contains_options; inline void check_for_no_dictionary_options(contains_options options) { if (options.as_key) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary" userInfo:nil] raise]; } else if (options.as_value) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary" userInfo:nil] raise]; } } inline void validate_contains_options_for_dictionary(contains_options options) { if (!options.as_key && !options.as_value) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of 'contain' matcher with dictionary; use the .as_a_key() or .as_a_value() modifiers" userInfo:nil] raise]; } } inline void validate_contains_options_for_string(contains_options options) { check_for_no_dictionary_options(options); if (options.nested) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of 'nested' modifier on 'contain' matcher with string" userInfo:nil] raise]; } } template bool compare_contains(const T & container, const U & element, NSString *elementKeyPath, contains_options options, F comparator) { check_for_no_dictionary_options(options); for (id object in elementKeyPath ? [container valueForKeyPath:elementKeyPath] : container) { if (comparator(object, element)) { return YES; } if (options.nested && [(elementKeyPath ? [object valueForKeyPath:elementKeyPath] : object) respondsToSelector:@selector(containsObject:)] && compare_contains(object, element, elementKeyPath, options, comparator)) { return YES; } } return NO; } #pragma mark array/vector/set template bool compare_contains(const T & container, const U & element, contains_options options, F comparator) { return compare_contains(container, element, nil, options, comparator); } template bool compare_contains(const T & container, const U & element, F comparator) { return container.end() != std::find_if(container.begin(), container.end(), [=](const U &lhs) { return comparator(lhs, element);}); } template bool compare_contains(const std::vector & container, const U & element, contains_options options, F comparator) { check_for_no_dictionary_options(options); return compare_contains(container, element, comparator); } template bool compare_contains(const std::vector & container, const U & element, contains_options options) { return compare_contains(container, element, options, [](const U & lhs, const U & rhs) { return compare_equal(lhs, rhs); }); } template bool compare_contains(const std::set & container, const U & element, contains_options options, F comparator) { check_for_no_dictionary_options(options); return compare_contains(container, element, comparator); } template bool compare_contains(const std::set & container, const U & element, contains_options options) { return compare_contains(container, element, options, [](const U & lhs, const U & rhs) { return compare_equal(lhs, rhs); }); } #pragma mark dictionary/map template bool compare_contains(NSDictionary * const container, const U & element, contains_options options, F comparator) { validate_contains_options_for_dictionary(options); contains_options original_options = options; options.as_key = options.as_value = false; if (original_options.as_key && compare_contains([container allKeys], element, nil, options, comparator)) { return true; } if (original_options.as_value && compare_contains([container allValues], element, nil, options, comparator)) { return true; } return false; } template bool compare_contains(NSDictionary * const container, const U & element, contains_options options) { return compare_contains(container, element, options, [](const U & lhs, const U & rhs) { return compare_equal(lhs, rhs); }); } template bool compare_contains(NSMutableDictionary * const container, const U & element, contains_options options) { return compare_contains(static_cast(container), element, options); } template bool compare_contains(NSMutableDictionary * const container, const U & element, contains_options options, F comparator) { return compare_contains(static_cast(container), element, options, comparator); } template bool compare_contains(const typename std::map & container, const V & element, contains_options options, F comparator) { validate_contains_options_for_dictionary(options); return container.end() != std::find_if(container.begin(), container.end(), [=](const typename std::map::value_type mapEntry) { if (options.as_key) { return comparator(mapEntry.first, element); } else { return comparator(mapEntry.second, element); } }); } template bool compare_contains(const typename std::map & container, const V & element, contains_options options) { return compare_contains(container, element, options, [](const U & lhs, const U & rhs) { return compare_equal(lhs, rhs); }); } #pragma mark string template bool compare_contains(NSString * const container, const U & element, NSString *elementKeyPath, contains_options options) { validate_contains_options_for_string(options); NSRange range = [container rangeOfString:element]; return container && range.location != NSNotFound; } template bool compare_contains(NSString * const container, const U & element, contains_options options) { return compare_contains(container, element, (NSString *)nil, options); } template bool compare_contains(NSMutableString * const container, const U & element, NSString *elementKeyPath, contains_options options) { return compare_contains(static_cast(container), element, elementKeyPath, options); } template bool compare_contains(NSMutableString * const container, const U & element, contains_options options) { return compare_contains(static_cast(container), element, (NSString *)nil, options); } template bool compare_contains(char *actualValue, const U & expectedContains, NSString *elementKeyPath, contains_options options) { validate_contains_options_for_string(options); return actualValue != NULL && strstr(actualValue, expectedContains) != NULL; } template bool compare_contains(char *actualValue, const U & expectedContains, contains_options options) { return compare_contains(actualValue, expectedContains, (NSString *)nil, options); } template bool compare_contains(const char *actualValue, const U & expectedContains, NSString *elementKeyPath, contains_options options) { return compare_contains((char *)actualValue, expectedContains, elementKeyPath, options); } template bool compare_contains(const char *actualValue, const U & expectedContains, contains_options options) { return compare_contains((char *)actualValue, expectedContains, (NSString *)nil, options); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Comparators/ComparatorsContainerConvenience.h ================================================ #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { template bool compare_contains(const T & container, const U & element, contains_options options) { return compare_contains(container, element, options, [](const U & lhs, const U & rhs) { return compare_equal(lhs, rhs); }); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Comparators/CompareCloseTo.h ================================================ #import "CDRSpecFailure.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { inline bool compare_close_to(const double actualValue, const double expectedValue, const double threshold) { return actualValue > expectedValue - threshold && actualValue < expectedValue + threshold; } inline bool compare_close_to(const NSDecimal & actualValue, const NSDecimal & expectedValue, const double threshold) { NSDecimal decimalThreshold = [@(threshold) decimalValue]; NSDecimal maxExpectedValue; NSDecimal minExpectedValue; NSDecimalAdd(&maxExpectedValue, &expectedValue, &decimalThreshold, NSRoundPlain); NSDecimalSubtract(&minExpectedValue, &expectedValue, &decimalThreshold, NSRoundPlain); return NSDecimalCompare(&actualValue, &minExpectedValue) != NSOrderedAscending && NSDecimalCompare(&actualValue, &maxExpectedValue) != NSOrderedDescending; } inline bool compare_close_to(const id actualValue, const id expectedValue, const double threshold) { if ([expectedValue isKindOfClass:[NSNumber class]] && [actualValue isKindOfClass:[NSNumber class]]) { return compare_close_to([actualValue decimalValue], [expectedValue decimalValue], threshold); } if ([expectedValue isKindOfClass:[NSDate class]] && [actualValue isKindOfClass:[NSDate class]]) { return compare_close_to([actualValue timeIntervalSince1970], [expectedValue timeIntervalSince1970], threshold); } NSString *reason = [NSString stringWithFormat:@"Actual value <%@> (%@) is not a numeric value (NSNumber, NSDate, float, etc.)", actualValue, NSStringFromClass([actualValue class])]; [[CDRSpecFailure specFailureWithReason:reason] raise]; return false; } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Comparators/CompareEqual.h ================================================ #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { #pragma mark Generic template bool compare_equal(const T & actualValue, const U & expectedValue) { if (strcmp(@encode(T), "@") == 0 && strcmp(@encode(U), "@") == 0) { NSValue *actualValueId = [NSValue value:&actualValue withObjCType:@encode(id)]; NSValue *expectedValueId = [NSValue value:&expectedValue withObjCType:@encode(id)]; return [[actualValueId nonretainedObjectValue] isEqual:[expectedValueId nonretainedObjectValue]]; } else { return actualValue == expectedValue; } } #pragma mark NSDecimal inline bool compare_equal(const NSDecimal & actualValue, const NSDecimal & expectedValue) { return NSOrderedSame == NSDecimalCompare(&actualValue, &expectedValue); } #pragma mark C Strings template bool compare_equal(char *actualValue, const U & expectedValue) { return strcmp(actualValue, expectedValue) == 0; } template bool compare_equal(const char *actualValue, const U & expectedValue) { return strcmp(actualValue, expectedValue) == 0; } #pragma mark NSRange template bool compare_equal(const NSRange actualValue, const U & expectedValue) { return NSEqualRanges(actualValue, expectedValue); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Comparators/CompareGreaterThan.h ================================================ #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { #pragma mark Generic template bool compare_greater_than(const T & actualValue, const U & expectedValue) { if (strcmp(@encode(T), "@") == 0 && strcmp(@encode(U), "@") == 0) { NSValue *actualValueId = [NSValue value:&actualValue withObjCType:@encode(id)]; NSValue *expectedValueId = [NSValue value:&expectedValue withObjCType:@encode(id)]; id actualValueObject = [actualValueId nonretainedObjectValue]; id expectedValueObject = [expectedValueId nonretainedObjectValue]; if ([actualValueObject respondsToSelector:@selector(compare:)]) { return NSOrderedDescending == [actualValueObject compare:expectedValueObject]; } else if ([expectedValueObject respondsToSelector:@selector(compare:)]) { return NSOrderedAscending == [expectedValueObject compare:actualValueObject]; } return false; } else { return actualValue > expectedValue; } } #pragma mark NSDecimal inline bool compare_greater_than(const NSDecimal & actualValue, const NSDecimal & expectedValue) { return NSOrderedDescending == NSDecimalCompare(&actualValue, &expectedValue); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Container/BeEmpty.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { class BeEmpty : public Base<> { private: BeEmpty & operator=(const BeEmpty &); public: inline BeEmpty() : Base<>() {} inline ~BeEmpty() {} // Allow default copy ctor. inline const BeEmpty & operator()() const { return *this; } template bool matches(const U &) const; protected: inline /*virtual*/ NSString * failure_message_end() const { return @"be empty"; } }; #pragma mark Generic template bool BeEmpty::matches(const U & actualValue) const { return Comparators::compare_empty(actualValue); } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { using CedarBeEmpty = Cedar::Matchers::Private::BeEmpty; static const CedarBeEmpty be_empty = CedarBeEmpty(); }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Container/Contain.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { template class Contain : public Base<> { private: Contain & operator=(const Contain &); public: explicit Contain(const T & element); ~Contain(); // Allow default copy ctor. Contain & nested(); Contain & as_a_key(); Contain & as_a_value(); template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: NSString *string_for_element() const; void validate_options() const; private: const T & element_; Comparators::contains_options options_; NSString *elementKeyPath_; }; template inline Contain::Contain(const T & element) : Base<>(), element_(element), options_({}) { } template Contain::~Contain() { } template Contain & Contain::nested() { options_.nested = true; return *this; } template Contain & Contain::as_a_key() { options_.as_key = true; validate_options(); return *this; } template Contain & Contain::as_a_value() { options_.as_value = true; validate_options(); return *this; } template inline /*virtual*/ NSString * Contain::failure_message_end() const { return [NSString stringWithFormat:@"contain <%@>%@%@", string_for_element(), options_.nested ? @" nested" : @"", options_.as_key ? @" as a key" : options_.as_value ? @" as a value" : @""]; } template inline NSString * Contain::string_for_element() const { return Stringifiers::string_for(element_); } template<> inline NSString * Contain::string_for_element() const { return element_.expected_class_string(); } template void Contain::validate_options() const { if (options_.as_key && options_.as_value) { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"Unexpected use of 'contain' matcher; use the .as_a_key() or .as_a_value() modifiers, but not both" userInfo:nil] raise]; } } #pragma mark Generic template template bool Contain::matches(const U & container) const { return Comparators::compare_contains(container, element_, options_); } template<> template bool Contain::matches(const U & container) const { return element_.matches(container, options_); } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarContain = Cedar::Matchers::Private::Contain; template inline CedarContain contain(const T & element) { return CedarContain(element); } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Container/ContainSubset.h ================================================ #import "Base.h" #ifdef __cplusplus #pragma mark - private interface namespace Cedar { namespace Matchers { namespace Private { template class ContainSubset : public Base<> { public: explicit ContainSubset(const T & element); ~ContainSubset(); // Allow default copy constructor. template bool matches(const U &) const; protected: virtual NSString * failure_message_end() const; private: template void validate_container_is_a_dictionary(const U &) const; void validate_subset_is_a_dictionary() const; const T & element_; Comparators::contains_options options_; NSString *elementKeyPath_; }; template inline ContainSubset::ContainSubset(const T & element) : Base<>(), element_(element), options_({}) { } template ContainSubset::~ContainSubset() { } template inline NSString * ContainSubset::failure_message_end() const { return [NSString stringWithFormat:@"contain subset <%@>", Stringifiers::string_for(element_)]; } #pragma mark Generic template template bool ContainSubset::matches(const U & container) const { validate_container_is_a_dictionary(container); validate_subset_is_a_dictionary(); NSDictionary *dictionary = (NSDictionary *)container; NSDictionary *possibleSubset = (NSDictionary *)element_; for (id key in possibleSubset) { if (![dictionary.allKeys containsObject:key]) { return false; } id value = possibleSubset[key]; if (![dictionary[key] isEqual:value]) { return false; } } return true; } #pragma mark Validations template template inline void ContainSubset::validate_container_is_a_dictionary(const U & container) const { BOOL isNotObjcObject = strncmp(@encode(U), "@", 1) != 0; if (isNotObjcObject || ![(id)container isKindOfClass:[NSDictionary class]]) { NSString *reason = [NSString stringWithFormat:@"Unexpected use of the 'contain_subset' matcher with non-dictionary container <%@>", Stringifiers::string_for(container)]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } } template inline void ContainSubset::validate_subset_is_a_dictionary() const { BOOL isNotObjcObject = strncmp(@encode(T), "@", 1) != 0; if (isNotObjcObject || ![(id)element_ isKindOfClass:[NSDictionary class]]) { NSString *reason = [NSString stringWithFormat:@"Unexpected use of the 'contain_subset' matcher with non-dictionary subset <%@>", Stringifiers::string_for(element_)]; [[NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil] raise]; } } }}} #pragma mark - public interface namespace Cedar { namespace Matchers { template using CedarContainSubset = Cedar::Matchers::Private::ContainSubset; template inline CedarContainSubset contain_subset(const T & element) { return CedarContainSubset(element); } }} #endif ================================================ FILE: Source/Headers/Public/Matchers/MatcherTemplate.h ================================================ #import "Base.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { template class <#MatcherClassName#> : public Base<> { private: <#MatcherClassName#> & operator=(const <#MatcherClassName#> &); public: explicit <#MatcherClassName#>(const T & expectedValue); ~<#MatcherClassName#>(); // Allow default copy ctor. template bool matches(const U &) const; // For pointer-specific matching. template bool matches(U * const &) const; // For type-specific matching bool matches(const <#SomeType#> &) const; protected: virtual NSString * failure_message_end() const; private: const T & expectedValue_; }; template <#MatcherClassName#> <#MatcherName#>(const T & expectedValue) { return <#MatcherClassName#>(expectedValue); } template <#MatcherClassName#>::<#MatcherClassName#>(const T & expectedValue) : Base<>(), expectedValue_(expectedValue) { } template <#MatcherClassName#>::~<#MatcherClassName#>() { } template /*virtual*/ NSString * <#MatcherClassName#>::failure_message_end() const { return [NSString stringWithFormat:@"be related in some way to <%@>", this->string_for(expectedValue_)]; } #pragma mark Generic template template bool <#MatcherClassName#>::matches(const U & actualValue) const { // return result of appropriate comparison } #pragma mark <#SomeType#> template bool <#MatcherClassName#>::matches(const <#SomeType#> & actualValue) const { // return result of appropriate comparison with specific type } }} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/OSX/OSXGeometryCompareEqual.h ================================================ #import "ComparatorsBase.h" #import "OSXGeometryStringifiers.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { template bool compare_equal(CGRect const actualValue, const U & expectedValue) { return CGRectEqualToRect(actualValue, expectedValue); } template bool compare_equal(CGSize const actualValue, const U & expectedValue) { return CGSizeEqualToSize(actualValue, expectedValue); } template bool compare_equal(CGPoint const actualValue, const U & expectedValue) { return CGPointEqualToPoint(actualValue, expectedValue); } template bool compare_equal(CGAffineTransform const actualValue, const U & expectedValue) { return CGAffineTransformEqualToTransform(actualValue, expectedValue); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/OSX/OSXGeometryStringifiers.h ================================================ #import "StringifiersBase.h" #ifdef __cplusplus #import namespace Cedar { namespace Matchers { namespace Stringifiers { inline NSString * string_for(const CGRect value) { return NSStringFromRect(value); } inline NSString * string_for(const CGSize value) { return NSStringFromSize(value); } inline NSString * string_for(const CGPoint value) { return NSStringFromPoint(value); } inline NSString * string_for(const CGAffineTransform value) { return [NSString stringWithFormat:@"[%g, %g, %g, %g, %g, %g]", value.a, value.b, value.c, value.d, value.tx, value.ty]; } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/ShouldSyntax.h ================================================ #import "ActualValue.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { struct ActualValueMarker { const char *fileName; int lineNumber; }; template const ActualValue operator,(const T & actualValue, const ActualValueMarker & marker) { return ActualValue(marker.fileName, marker.lineNumber, actualValue); } template const ActualValueMatchProxy operator,(const ActualValue & actualValue, bool negate) { return negate ? actualValue.to_not : actualValue.to; } template void operator,(const ActualValueMatchProxy & matchProxy, const MatcherType & matcher) { matchProxy(matcher); } }} #ifndef CEDAR_MATCHERS_DISALLOW_SHOULD #define should ,(ActualValueMarker){__FILE__, __LINE__},false, #define should_not ,(ActualValueMarker){__FILE__, __LINE__},true, #endif #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Stringifiers/StringifiersBase.h ================================================ #import #ifdef __cplusplus #include namespace Cedar { namespace Matchers { namespace Stringifiers { NSString * object_description_for(const void *objectValue); template NSString * string_for(const U & value) { if (0 == strncmp(@encode(U), "@", 1)) { return object_description_for(&value); } else { std::stringstream temp; temp << value; return [NSString stringWithCString:temp.str().c_str() encoding:NSUTF8StringEncoding]; } } inline NSString * string_for(std::nullptr_t value) { return @"nil"; } inline NSString * string_for(const char value) { return string_for(static_cast(value)); } inline NSString * string_for(const Class & value) { return NSStringFromClass(value); } inline NSString * string_for(const BOOL value) { return value ? @"YES" : @"NO"; } inline NSString * string_for(NSNumber * const value) { if (!value) { return [NSString stringWithFormat:@"%@", value]; } return string_for([value floatValue]); } inline NSString * string_for(const NSDecimal value) { return NSDecimalString(&value, [NSLocale systemLocale]); } inline NSString * string_for(char *value) { if (value == NULL) { return @"NULL"; } return [NSString stringWithFormat:@"cstring(%s)", value]; } inline NSString * string_for(const char *value) { return string_for((char *)value); } inline NSString * string_for(NSRange value) { return NSStringFromRange(value); } inline NSString * string_for(NSDate *date) { return [NSString stringWithFormat:@"%@ (%f)", date, [date timeIntervalSince1970]]; } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/Stringifiers/StringifiersContainer.h ================================================ #ifdef __cplusplus #import #import #import namespace Cedar { namespace Matchers { namespace Stringifiers { namespace { template NSString * comma_and_newline_delimited_list(const Container & container) { NSMutableString *result = [NSMutableString string]; bool first = true; for (typename Container::const_iterator it = container.begin(); it != container.end(); ++it, first = false) { if (!first) { [result appendString:@","]; } NSString * string = string_for(*it); [result appendString:[NSString stringWithFormat:@"\n %@", string]]; } return result; } } template NSString * string_for(const typename std::vector & container) { NSString * delimitedList = comma_and_newline_delimited_list(container); return [NSString stringWithFormat:@"(%@\n)", delimitedList]; } template NSString * string_for(const typename std::map & container) { NSMutableString *result = [NSMutableString stringWithString:@"{"]; for (typename std::map::const_iterator it = container.begin(); it != container.end(); ++it) { NSString * keyString = string_for(it->first); NSString * valueString = string_for(it->second); [result appendString:[NSString stringWithFormat:@"\n %@ = %@;", keyString, valueString]]; } [result appendString:@"\n}"]; return result; } template NSString * string_for(const typename std::set & container) { NSString * delimitedList = comma_and_newline_delimited_list(container); return [NSString stringWithFormat:@"{(%@\n)}", delimitedList]; } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/UIKit/UIGeometryCompareEqual.h ================================================ #import #import #import "ComparatorsBase.h" #import "UIGeometryStringifiers.h" #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { template bool compare_equal(CGRect const actualValue, const U & expectedValue) { return CGRectEqualToRect(actualValue, expectedValue); } template bool compare_equal(CGSize const actualValue, const U & expectedValue) { return CGSizeEqualToSize(actualValue, expectedValue); } template bool compare_equal(CGPoint const actualValue, const U & expectedValue) { return CGPointEqualToPoint(actualValue, expectedValue); } template bool compare_equal(UIEdgeInsets const actualValue, const U & expectedValue) { return UIEdgeInsetsEqualToEdgeInsets(actualValue, expectedValue); } template bool compare_equal(CGAffineTransform const actualValue, const U & expectedValue) { return CGAffineTransformEqualToTransform(actualValue, expectedValue); } template bool compare_equal(UIImage *actualImage, const U & expectedImage) { return [expectedImage isEqual:actualImage] || [UIImagePNGRepresentation(expectedImage) isEqual:UIImagePNGRepresentation(actualImage)]; } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/UIKit/UIGeometryStringifiers.h ================================================ #import #import "StringifiersBase.h" #ifdef __cplusplus #import namespace Cedar { namespace Matchers { namespace Stringifiers { inline NSString * string_for(const CGRect value) { return NSStringFromCGRect(value); } inline NSString * string_for(const CGSize value) { return NSStringFromCGSize(value); } inline NSString * string_for(const CGPoint value) { return NSStringFromCGPoint(value); } inline NSString * string_for(const UIEdgeInsets value) { return NSStringFromUIEdgeInsets(value); } inline NSString * string_for(const CGAffineTransform value) { return NSStringFromCGAffineTransform(value); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Matchers/UIKit/iOS/UIKitComparatorsContainer.h ================================================ #import #import #ifdef __cplusplus namespace Cedar { namespace Matchers { namespace Comparators { template bool compare_contains(UIView * const container, const U & element, contains_options options, F comparator) { return compare_contains(container, element, @"subviews", options, comparator); } template bool compare_contains(CALayer * const container, const U & element, contains_options options, F comparator) { return compare_contains(container, element, @"sublayers", options, comparator); } }}} #endif // __cplusplus ================================================ FILE: Source/Headers/Public/Reporters/CDRBufferedDefaultReporter.h ================================================ #import "CDRDefaultReporter.h" @interface CDRBufferedDefaultReporter : CDRDefaultReporter @property (retain, nonatomic) NSMutableString *buffer; #pragma mark Overrides - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed; - (void)runDidComplete; - (void)logText:(NSString *)linePartial; @end ================================================ FILE: Source/Headers/Public/Reporters/CDRColorizedReporter.h ================================================ #import #import "CDRBufferedDefaultReporter.h" @interface CDRColorizedReporter : CDRBufferedDefaultReporter @end ================================================ FILE: Source/Headers/Public/Reporters/CDRDefaultReporter.h ================================================ #import "CDRExampleReporter.h" @class CDRExample; @interface CDRDefaultReporter : NSObject { NSString *cedarVersionString_; NSArray *rootGroups_; NSMutableArray *pendingMessages_; NSMutableArray *skippedMessages_; NSMutableArray *failureMessages_; NSDate *startTime_; NSDate *endTime_; unsigned int exampleCount_; } - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString; @end @interface CDRDefaultReporter (Protected) @property (nonatomic) unsigned int exampleCount; - (NSString *)successToken; - (NSString *)pendingToken; - (NSString *)pendingMessageForExample:(CDRExample *)example; - (NSString *)skippedToken; - (NSString *)skippedMessageForExample:(CDRExample *)example; - (NSString *)failureToken; - (NSString *)failureMessageForExample:(CDRExample *)example; - (NSString *)errorToken; - (NSString *)errorMessageForExample:(CDRExample *)example; - (void)reportOnExample:(CDRExample *)example; - (void)printStats; - (void)logText:(NSString *)linePartial; @end ================================================ FILE: Source/Headers/Public/Reporters/CDRExampleReporter.h ================================================ #import #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN @class CDRExample, CDRExampleGroup, CDRSpec; @protocol CDRExampleReporter - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed; - (void)runDidComplete; - (int)result; // new methods to use instead of KVO @required - (void)runWillStartExample:(CDRExample *)example; - (void)runDidFinishExample:(CDRExample *)example; - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup; - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup; - (void)runWillStartSpec:(CDRSpec *)spec; - (void)runDidFinishSpec:(CDRSpec *)spec; @end NS_ASSUME_NONNULL_END ================================================ FILE: Source/Headers/Public/Reporters/CDRJUnitXMLReporter.h ================================================ #import #import "CDRDefaultReporter.h" @interface CDRJUnitXMLReporter : CDRDefaultReporter { NSMutableArray *successExamples_; NSMutableArray *failureExamples_; } @end ================================================ FILE: Source/Headers/Public/Reporters/CDROTestReporter.h ================================================ #import "CDRExampleReporter.h" @interface CDROTestReporter : NSObject - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString; @end ================================================ FILE: Source/Headers/Public/Reporters/CDRTeamCityReporter.h ================================================ #import #import "CDRDefaultReporter.h" @interface CDRTeamCityReporter : CDRDefaultReporter { } @end ================================================ FILE: Source/Headers/Public/Reporters/CedarReporters.h ================================================ #import "CDRColorizedReporter.h" #import "CDRDefaultReporter.h" #import "CDRExampleReporter.h" #import "CDRJUnitXMLReporter.h" #import "CDROTestReporter.h" #import "CDRTeamCityReporter.h" #import "CDRBufferedDefaultReporter.h" ================================================ FILE: Source/Headers/Public/iOS/Cedar-iOS.h ================================================ // This header still exists only for backwards-compatibility #import "Cedar.h" ================================================ FILE: Source/Headers/Public/iOS/CedarApplicationDelegate.h ================================================ #import // In some cases CDRIPhoneOTestRunner needs to spin up an instance of Cedar app. // It appears that SenTestingKit fails to start up the test when CedarApplicationDelegate // is used. Solution is to use a subclass of UIApplicaton. @interface CedarApplication : UIApplication @end // Needed for backwards compatibility with existing projects using CedarApplicationDelegate @interface CedarApplicationDelegate : NSObject @end ================================================ FILE: Source/Matchers/Base/ConformTo.mm ================================================ #import #import "ConformTo.h" namespace Cedar { namespace Matchers { namespace Private { ConformTo::ConformTo(Protocol *protocol) : expectedProtocolName_([NSStringFromProtocol(protocol) UTF8String]) {} ConformTo::ConformTo(const char *protocolName) : expectedProtocolName_(protocolName) {} ConformTo::~ConformTo() {} /*virtual*/ NSString *ConformTo::failure_message_end() const { return [NSString stringWithFormat:@"conform to <%@> protocol", @(expectedProtocolName_)]; } /*virtual*/ bool ConformTo::matches(const id subject) const { return [subject conformsToProtocol:NSProtocolFromString(@(expectedProtocolName_))]; } }}} ================================================ FILE: Source/Matchers/Base/RaiseException.mm ================================================ #import "RaiseException.h" namespace Cedar { namespace Matchers { namespace Private { #pragma mark - RaiseException RaiseException::RaiseException(NSObject *expectedExceptionInstance /*= nil */, Class expectedExceptionClass /*= nil */, bool allowSubclasses /*= false */, NSString *reason /*= nil */, NSString *name /* = nil */) : Base(), expectedExceptionInstance_([expectedExceptionInstance retain]), expectedExceptionClass_(expectedExceptionClass), allowSubclasses_(allowSubclasses), expectedReason_([reason retain]), expectedName_([name retain]) { } RaiseException::~RaiseException() { [expectedExceptionInstance_ release]; [expectedReason_ release]; [expectedName_ release]; } RaiseException RaiseException::operator()() const { return RaiseException(); } RaiseException RaiseException::operator()(Class expectedExceptionClass) const { return RaiseException(nil, expectedExceptionClass); } RaiseException RaiseException::operator()(NSObject *expectedExceptionInstance) const { return RaiseException(expectedExceptionInstance); } RaiseException & RaiseException::or_subclass() { allowSubclasses_ = true; return *this; } RaiseException & RaiseException::with_reason(NSString * const reason) { expectedReason_ = [reason retain]; return *this; } RaiseException RaiseException::with_reason(NSString * const reason) const { return RaiseException(nil, nil, false, reason, nil); } RaiseException & RaiseException::with_name(NSString *const name) { expectedName_ = [name retain]; return *this; } RaiseException RaiseException::with_name(NSString *const name) const { return RaiseException(nil, nil, false, nil, name); } #pragma mark - Exception matcher bool RaiseException::matches(empty_block_t block) const { @try { block(); } @catch (NSObject *exception) { return this->exception_matches_expected_class(exception) && this->exception_matches_expected_instance(exception) && this->exception_matches_expected_name(exception) && this->exception_matches_expected_reason(exception); } return false; } /*virtual*/ NSString * RaiseException::failure_message_end() const { NSMutableString *message = [NSMutableString stringWithFormat:@"raise an exception"]; if (expectedExceptionClass_) { [message appendString:@" of class"]; if (allowSubclasses_) { [message appendString:@", or subclass of class,"]; } [message appendFormat:@" <%@>", NSStringFromClass(expectedExceptionClass_)]; } if (expectedName_) { [message appendFormat:@" with name <%@>", expectedName_]; if (expectedReason_) { [message appendFormat:@" and reason <%@>", expectedReason_]; } } else if (expectedReason_) { [message appendFormat:@" with reason <%@>", expectedReason_]; } return message; } #pragma mark - Private interface bool RaiseException::exception_matches_expected_class(NSObject * const exception) const { return !expectedExceptionClass_ || (allowSubclasses_ ? [exception isKindOfClass:expectedExceptionClass_] : [exception isMemberOfClass:expectedExceptionClass_]); } bool RaiseException::exception_matches_expected_instance(NSObject * const exception) const { return !expectedExceptionInstance_ || [expectedExceptionInstance_ isEqual:exception]; } bool RaiseException::exception_matches_expected_reason(NSObject * const exception) const { return !expectedReason_ || ([exception isKindOfClass:[NSException class]] && [expectedReason_ isEqualToString:[id(exception) reason]]); } bool RaiseException::exception_matches_expected_name(NSObject *const exception) const { return !expectedName_ || ([exception isKindOfClass:[NSException class]] && [expectedName_ isEqualToString:[id(exception) name]]); } }}} ================================================ FILE: Source/Matchers/Base/RespondTo.mm ================================================ #import #import "RespondTo.h" namespace Cedar { namespace Matchers { namespace Private { RespondTo::RespondTo(SEL selector) : expectedSelectorName_([NSStringFromSelector(selector) UTF8String]) {} RespondTo::RespondTo(const char *selectorName) : expectedSelectorName_(selectorName) {} RespondTo::~RespondTo() {} /*virtual*/ NSString *RespondTo::failure_message_end() const { return [NSString stringWithFormat:@"respond to <%@> selector", @(expectedSelectorName_)]; } /*virtual*/ bool RespondTo::matches(const id subject) const { return [subject respondsToSelector:NSSelectorFromString(@(expectedSelectorName_))]; } }}} ================================================ FILE: Source/Matchers/Stringifiers/StringifiersBase.mm ================================================ #import "StringifiersBase.h" #import namespace Cedar { namespace Matchers { namespace Stringifiers { NSString * object_description_for(const void *objectValue) { NSValue *valueId = [NSValue valueWithBytes:objectValue objCType:@encode(id)]; id object = [valueId nonretainedObjectValue]; Class klass = object_getClass(object); if (object && class_getInstanceMethod(klass, @selector(description)) == NULL) { return [NSString stringWithFormat:@"%@ %p", NSStringFromClass(klass), object]; } else { return [NSString stringWithFormat:@"%@", [[valueId nonretainedObjectValue] description]]; } } }}} ================================================ FILE: Source/ReporterHelpers/CDROTestNamer.m ================================================ #import "CDROTestNamer.h" #import "CDRExample.h" #import "CDRExampleBase.h" @interface CDROTestNamer () @property (nonatomic, retain) NSMutableCharacterSet *allowedCharacterSet; @property (nonatomic, retain) NSMutableSet *unavailableNamesForClasses; @end @implementation CDROTestNamer - (void)dealloc { self.unavailableNamesForClasses = nil; self.allowedCharacterSet = nil; [super dealloc]; } - (id)init { self = [super init]; if (self) { self.unavailableNamesForClasses = [NSMutableSet set]; self.allowedCharacterSet = [[[NSCharacterSet alphanumericCharacterSet] mutableCopy] autorelease]; [self.allowedCharacterSet addCharactersInString:@"_"]; } return self; } - (NSString *)classNameForExample:(CDRExampleBase *)example { NSString *className = NSStringFromClass([example.spec class]); className = className ?: @"Cedar"; return [self sanitizeNameFromString:className]; } - (NSString *)methodNameForExample:(CDRExampleBase *)example withClassName:(NSString *)className { NSMutableArray *fullTextPieces = [example.fullTextInPieces mutableCopy]; NSString *specClassName = [self sanitizeNameFromString:className]; NSString *firstPieceWithSpecPostfix = [NSString stringWithFormat:@"%@Spec", [fullTextPieces objectAtIndex:0]]; if ([firstPieceWithSpecPostfix isEqual:specClassName]) { [fullTextPieces removeObjectAtIndex:0]; } NSString *methodName = [fullTextPieces componentsJoinedByString:@"_"]; [fullTextPieces release]; NSString *sanitizedPotentialName = [self sanitizeNameFromString:methodName]; NSString *sanitizedName = sanitizedPotentialName; NSUInteger i = 0; while ([self.unavailableNamesForClasses containsObject:[self fullNameWithClassName:className methodName:sanitizedName]]) { i++; sanitizedName = [sanitizedPotentialName stringByAppendingFormat:@"_%lu", (unsigned long)i]; } [self.unavailableNamesForClasses addObject:[self fullNameWithClassName:className methodName:sanitizedName]]; return sanitizedName; } - (NSString *)methodNameForExample:(CDRExampleBase *)example { return [self methodNameForExample:example withClassName:[self classNameForExample:example]]; } #pragma mark - Private - (NSString *)fullNameWithClassName:(NSString *)className methodName:(NSString *)methodName { return [NSString stringWithFormat:@"%@ %@", className, methodName]; } - (NSString *)sanitizeNameFromString:(NSString *)string { NSMutableString *mutableString = [string mutableCopy]; [mutableString replaceOccurrencesOfString:@" " withString:@"_" options:0 range:NSMakeRange(0, mutableString.length)]; for (NSUInteger i=0; i 0 && (titleChunk.length + 1 + currentLineLength > 70)) { [lines addObject:[currentLine componentsJoinedByString:@" "]]; currentLine = [NSMutableArray array]; currentLineLength = 0; } [currentLine addObject:titleChunk]; currentLineLength += titleChunk.length + 1; } [lines addObject:[currentLine componentsJoinedByString:@" "]]; return [timeString stringByAppendingString:[lines componentsJoinedByString:newLinePrefix]]; } - (NSComparisonResult)compare:(CDRRunTimeTitlePair *)otherPair { if (self.runTime > otherPair.runTime) { return NSOrderedDescending; } else if (self.runTime < otherPair.runTime) { return NSOrderedAscending; } return NSOrderedSame; } @end @interface CDRSlowTestStatistics () - (int)numberOfResultsToShow; - (NSArray *)runTimeTitlePairsForGroup:(CDRExampleGroup *)group; @end @implementation CDRSlowTestStatistics - (int)numberOfResultsToShow { int numberOfResultsToShow = 10; if (getenv("CEDAR_TOP_N_SLOW_TESTS")) { numberOfResultsToShow = [[NSString stringWithUTF8String:getenv("CEDAR_TOP_N_SLOW_TESTS")] intValue]; } return numberOfResultsToShow; } - (void)printStatsForExampleGroups:(NSArray *)groups { NSMutableArray *rootPairs = [NSMutableArray array]; NSMutableArray *examplePairs = [NSMutableArray array]; for (CDRExampleGroup *group in groups) { [rootPairs addObject:[CDRRunTimeTitlePair pairWithRunTime:group.runTime title:group.text]]; [examplePairs addObjectsFromArray:[self runTimeTitlePairsForGroup:group]]; } int numberOfResultsToShow = self.numberOfResultsToShow; NSArray *sortedRootPairs = [[[rootPairs sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; sortedRootPairs = [sortedRootPairs subarrayWithRange:NSMakeRange(0, MIN(numberOfResultsToShow, sortedRootPairs.count))]; NSArray *sortedExamplePairs = [[[examplePairs sortedArrayUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; sortedExamplePairs = [sortedExamplePairs subarrayWithRange:NSMakeRange(0, MIN(numberOfResultsToShow, sortedExamplePairs.count))]; printf("\n%d Slowest Tests\n\n", (int)sortedExamplePairs.count); for (CDRRunTimeTitlePair *pair in sortedExamplePairs) { printf("%s\n\n", pair.formattedDescription.UTF8String); } printf("\n%d Slowest Top-Level Groups\n\n", (int)sortedRootPairs.count); for (CDRRunTimeTitlePair *pair in sortedRootPairs) { printf("%s\n\n", pair.formattedDescription.UTF8String); } } - (NSArray *)runTimeTitlePairsForGroup:(CDRExampleGroup *)group { NSMutableArray *pairs = [NSMutableArray array]; if (group.hasChildren) { for (CDRExampleBase *example in group.examples) { if (example.hasChildren) { [pairs addObjectsFromArray:[self runTimeTitlePairsForGroup:(CDRExampleGroup *) example]]; } else { [pairs addObject:[CDRRunTimeTitlePair pairWithRunTime:example.runTime title:example.fullText]]; } } } return pairs; } @end ================================================ FILE: Source/Reporters/CDRBufferedDefaultReporter.m ================================================ #import "CDRBufferedDefaultReporter.h" @implementation CDRBufferedDefaultReporter - (void)dealloc { self.buffer = nil; [super dealloc]; } #pragma mark Overrides - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed { self.buffer = [NSMutableString string]; [super runWillStartWithGroups:groups andRandomSeed:seed]; } - (void)runDidComplete { [super runDidComplete]; printf("%s", [self.buffer UTF8String]); } - (void)logText:(NSString *)linePartial { [self.buffer appendString:linePartial]; } @end ================================================ FILE: Source/Reporters/CDRColorizedReporter.m ================================================ #import "CDRColorizedReporter.h" static const char * const ANSI_NORMAL = "\033[0m"; static const char * const ANSI_RED = "\033[0;40;31m"; static const char * const ANSI_GREEN = "\033[0;40;32m"; static const char * const ANSI_YELLOW = "\033[0;40;33m"; static const char * const ANSI_CYAN = "\033[0;40;36m"; @implementation CDRColorizedReporter #pragma mark Protected interface - (NSString *)successToken { return [NSString stringWithFormat:@"%s%@%s", ANSI_GREEN, [super successToken], ANSI_NORMAL]; } - (NSString *)pendingToken { return [NSString stringWithFormat:@"%s%@%s", ANSI_YELLOW, [super pendingToken], ANSI_NORMAL]; } - (NSString *)pendingMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"%s%@%s", ANSI_YELLOW, [super pendingMessageForExample:example], ANSI_NORMAL]; } - (NSString *)skippedToken { return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedToken], ANSI_NORMAL]; } - (NSString *)skippedMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedMessageForExample:example], ANSI_NORMAL]; } - (NSString *)failureToken { return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super failureToken], ANSI_NORMAL]; } - (NSString *)failureMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super failureMessageForExample:example], ANSI_NORMAL]; } - (NSString *)errorToken { return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super errorToken], ANSI_NORMAL]; } - (NSString *)errorMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super errorMessageForExample:example], ANSI_NORMAL]; } @end ================================================ FILE: Source/Reporters/CDRDefaultReporter.m ================================================ #import "CDRDefaultReporter.h" #import "CDRExample.h" #import "CDRExampleGroup.h" #import "CDRSymbolicator.h" #import "CDRSpecHelper.h" #import "CDRSlowTestStatistics.h" @interface CDRDefaultReporter (private) - (void)printMessages:(NSArray *)messages; - (void)reportOnExample:(CDRExample *)example; - (void)printStats; @end @implementation CDRDefaultReporter #pragma mark Memory - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString { if (self = [super init]) { cedarVersionString_ = [cedarVersionString retain]; pendingMessages_ = [[NSMutableArray alloc] init]; skippedMessages_ = [[NSMutableArray alloc] init]; failureMessages_ = [[NSMutableArray alloc] init]; exampleCount_ = 0; } return self; } - (void)dealloc { [cedarVersionString_ release]; [rootGroups_ release]; [startTime_ release]; [endTime_ release]; [failureMessages_ release]; [skippedMessages_ release]; [pendingMessages_ release]; [super dealloc]; } #pragma mark Public interface - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed { rootGroups_ = [groups retain]; startTime_ = [[NSDate alloc] init]; [self logText:[NSString stringWithFormat:@"Cedar Version: %@\n", cedarVersionString_]]; [self logText:[NSString stringWithFormat:@"Running With Random Seed: %i\n\n", seed]]; } - (void)runDidComplete { endTime_ = [[NSDate alloc] init]; [self logText:@"\n"]; if ([pendingMessages_ count]) { [self printMessages:pendingMessages_]; } if ([failureMessages_ count]) { [self printMessages:failureMessages_]; } [self printStats]; } - (int)result { if ([CDRSpecHelper specHelper].shouldOnlyRunFocused || [failureMessages_ count]) { return 1; } else { return 0; } } - (void)runWillStartExample:(CDRExample *)example { exampleCount_++; } - (void)runDidFinishExample:(CDRExample *)example { [self reportOnExample:example]; } - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup { } - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup { } - (void)runWillStartSpec:(CDRSpec *)spec { } - (void)runDidFinishSpec:(CDRSpec *)spec { } #pragma mark Protected interface - (void)logText:(NSString *)linePartial { printf("%s", [linePartial UTF8String]); } - (unsigned int)exampleCount { return exampleCount_; } - (NSString *)successToken { return @"."; } - (NSString *)pendingToken { return @"P"; } - (NSString *)pendingMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"PENDING %@", [example fullText]]; } - (NSString *)skippedToken { return @">"; } - (NSString *)skippedMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"SKIPPED %@", [example fullText]]; } - (NSString *)failureToken { return @"F"; } - (NSString *)failureMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"FAILURE %@\n%@\n", example.fullText, example.failure]; } - (NSString *)errorToken { return @"E"; } - (NSString *)errorMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"EXCEPTION %@\n%@\n%@", example.fullText, example.failure, [self callStackSymbolsForFailure:example.failure]]; } - (NSString *)callStackSymbolsForFailure:(CDRSpecFailure *)failure { // Currently to symbolicate an exception // we shell out to atos; thus this opt-in setting. if (!getenv("CEDAR_SYMBOLICATE_EXCEPTIONS")) return nil; NSError *error = nil; NSString *callStackSymbols = [failure callStackSymbolicatedSymbols:&error]; if (error.domain == kCDRSymbolicatorErrorDomain) { if (error.code == kCDRSymbolicatorErrorNotSuccessful) { NSString *details = [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey]; [self logText:[NSString stringWithFormat: @"Exception symbolication was not successful.\n" @"To turn it off remove CEDAR_SYMBOLICATE_EXCEPTIONS.\n" @"Details:\n%@\n", details]]; } } return callStackSymbols; } #pragma mark Private interface - (void)printMessages:(NSArray *)messages { [self logText:@"\n"]; for (NSString *message in messages) { [self logText:[NSString stringWithFormat:@"%@\n", message]]; } } - (void)printNestedFullTextForExample:(CDRExample *)example stateToken:(NSString *)token { static NSMutableArray *previousBranch = nil; NSUInteger previousBranchLength = previousBranch.count; NSMutableArray *exampleBranch = [example fullTextInPieces]; NSUInteger exampleBranchLength = exampleBranch.count; BOOL onPreviousBranch = YES; for (int i=0; i i && [[exampleBranch objectAtIndex:i] isEqualToString:[previousBranch objectAtIndex:i]]); if (!onPreviousBranch) { NSString *indicator = (exampleBranchLength - i) == 1 ? token : @" "; [self logText:[NSString stringWithFormat:@"%@ %*s%@\n", indicator, 2*i, "", [exampleBranch objectAtIndex:i]]]; } } [previousBranch release]; previousBranch = exampleBranch; [[previousBranch retain] removeLastObject]; } - (void)reportOnExample:(CDRExample *)example { NSString *stateToken = nil; switch (example.state) { case CDRExampleStatePassed: stateToken = [self successToken]; break; case CDRExampleStatePending: stateToken = [self pendingToken]; [pendingMessages_ addObject:[self pendingMessageForExample:example]]; break; case CDRExampleStateSkipped: stateToken = [self skippedToken]; [skippedMessages_ addObject:[self skippedMessageForExample:example]]; break; case CDRExampleStateFailed: stateToken = [self failureToken]; [failureMessages_ addObject:[self failureMessageForExample:example]]; break; case CDRExampleStateError: stateToken = [self errorToken]; [failureMessages_ addObject:[self errorMessageForExample:example]]; break; default: break; } const char *reporterOpts = getenv("CEDAR_REPORTER_OPTS"); if (reporterOpts && strcmp(reporterOpts, "nested") == 0) { [self printNestedFullTextForExample:example stateToken:stateToken]; } else { [self logText:stateToken]; } if (getenv("CEDAR_REPORT_FAILURES_IMMEDIATELY")) { if (example.state == CDRExampleStateFailed || example.state == CDRExampleStateError) { [self logText:[NSString stringWithFormat:@"\n%@", [failureMessages_ lastObject]]]; } } } - (void)printStats { [self logText:[NSString stringWithFormat:@"\nFinished in %.4f seconds\n\n", [endTime_ timeIntervalSinceDate:startTime_]]]; [self logText:[NSString stringWithFormat:@"%u examples, %u failures", exampleCount_, (unsigned int)failureMessages_.count]]; if (pendingMessages_.count) { [self logText:[NSString stringWithFormat:@", %u pending", (unsigned int)pendingMessages_.count]]; } if (skippedMessages_.count) { [self logText:[NSString stringWithFormat:@", %u skipped", (unsigned int)skippedMessages_.count]]; } [self logText:@"\n"]; if (getenv("CEDAR_REPORT_SLOW_TESTS")) { CDRSlowTestStatistics *slowTestStats = [[[CDRSlowTestStatistics alloc] init] autorelease]; [slowTestStats printStatsForExampleGroups:rootGroups_]; } } @end ================================================ FILE: Source/Reporters/CDRJUnitXMLReporter.m ================================================ #import "CDRJUnitXMLReporter.h" #import "CDRExample.h" #import "CDRSpec.h" #import "CDROTestNamer.h" @interface CDRJUnitXMLReporter () @property (nonatomic, retain) CDROTestNamer * namer; @end @implementation CDRJUnitXMLReporter - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString { self = [super initWithCedarVersion:cedarVersionString]; if (self = [super init]) { successExamples_ = [[NSMutableArray alloc] init]; failureExamples_ = [[NSMutableArray alloc] init]; self.namer = [[[CDROTestNamer alloc] init] autorelease]; } return self; } - (void)dealloc { [successExamples_ release]; [failureExamples_ release]; self.namer = nil; [super dealloc]; } #pragma mark - Overriden Methods - (NSString *)failureMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"%@\n%@\n", example.fullText, example.failure]; } - (void)reportOnExample:(CDRExample *)example { switch (example.state) { case CDRExampleStatePassed: [successExamples_ addObject:example]; break; case CDRExampleStateFailed: case CDRExampleStateError: [failureMessages_ addObject:[self failureMessageForExample:example]]; [failureExamples_ addObject:example]; break; default: break; } } - (void)runDidComplete { [super runDidComplete]; NSMutableString *xml = [NSMutableString string]; [xml appendString:@"\n"]; [xml appendString:@"\n"]; for (CDRExample *example in successExamples_) { NSString *className = [self.namer classNameForExample:example]; [xml appendFormat:@"\t\n", [self escapeString:className], [self escapeString:example.fullText], example.runTime]; } for (CDRExample *example in failureExamples_) { NSString *failureMessage = [self failureMessageForExample:example]; NSArray *parts = [failureMessage componentsSeparatedByString:@"\n"]; NSString *testCaseName = [parts objectAtIndex:0]; NSString *failureDescription = [parts objectAtIndex:1]; NSString *className = [self.namer classNameForExample:example]; [xml appendFormat:@"\t\n", [self escapeString:className], [self escapeString:testCaseName], example.runTime]; [xml appendFormat:@"\t\t%@\n", [self escapeString:failureDescription]]; [xml appendString:@"\t\n"]; } [xml appendString:@"\n"]; [self writeXmlToFile:xml]; } #pragma mark - Private - (NSString *)escapeString:(NSString *)unescaped { NSString *escaped = [unescaped stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; escaped = [escaped stringByReplacingOccurrencesOfString:@">" withString:@">"]; escaped = [escaped stringByReplacingOccurrencesOfString:@"<" withString:@"<"]; escaped = [escaped stringByReplacingOccurrencesOfString:@"\"" withString:@"""]; return [escaped stringByReplacingOccurrencesOfString:@"'" withString:@"'"]; } - (void)writeXmlToFile:(NSString *)xml { char *xmlFile = getenv("CEDAR_JUNIT_XML_FILE"); if (!xmlFile) xmlFile = "build/TEST-Cedar.xml"; [xml writeToFile:[NSString stringWithUTF8String:xmlFile] atomically:YES encoding:NSUTF8StringEncoding error:NULL]; } @end ================================================ FILE: Source/Reporters/CDROTestReporter.m ================================================ #import "CDROTestReporter.h" #import "CDRPrivateFunctions.h" #import "CDRExample.h" #import "CDRExampleGroup.h" #import "CDRSpecHelper.h" #import "CDRSpec.h" #import "CDROTestNamer.h" @interface CDROTestReporter () @property (retain, nonatomic) NSString *cedarVersionString; @property (retain, nonatomic) NSDate *startTime; @property (retain, nonatomic) NSDate *endTime; @property (retain, nonatomic) NSDateFormatter *formatter; @property (retain, nonatomic) CDROTestNamer *namer; @property (retain, nonatomic) NSString *currentMethodName; @property (retain, nonatomic) NSString *currentSuiteName; @property (retain, nonatomic) CDRExampleGroup *currentSuite; @property (retain, nonatomic) NSArray *rootGroups; @property (assign, nonatomic) NSUInteger failedCount; @end @implementation CDROTestReporter - (void)dealloc { self.cedarVersionString = nil; self.startTime = nil; self.endTime = nil; self.formatter = nil; self.currentSuiteName = nil; self.currentSuite = nil; self.rootGroups = nil; self.namer = nil; [super dealloc]; } - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString { self = [super init]; if (self) { self.formatter = [[[NSDateFormatter alloc] init] autorelease]; [self.formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss Z"]; self.namer = [[[CDROTestNamer alloc] init] autorelease]; self.cedarVersionString = cedarVersionString; } return self; } #pragma mark - - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed { self.startTime = [NSDate date]; self.rootGroups = groups; [self logMessage:[NSString stringWithFormat:@"Cedar Version: %@", self.cedarVersionString]]; [self logMessage:[NSString stringWithFormat:@"Cedar Random Seed: %d", seed]]; [self startSuite:[self rootSuiteName] atDate:self.startTime]; [self startSuite:[self bundleSuiteName] atDate:self.startTime]; } - (void)runDidComplete { if (self.currentSuiteName) { [self finishSuite:self.currentSuiteName atDate:[NSDate date]]; [self printStatsForExamples:@[self.currentSuite]]; } self.endTime = [NSDate date]; [self finishSuite:[self bundleSuiteName] atDate:self.endTime]; [self printStatsForExamples:self.rootGroups]; [self finishSuite:[self rootSuiteName] atDate:self.endTime]; [self printStatsForExamples:self.rootGroups]; } - (int)result { if ([self isFocused] || self.failedCount) { return 1; } else { return 0; } } - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup {} - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup {} - (void)runWillStartExample:(CDRExample *)example { if ([self shouldReportExample:example]) { NSString *testSuite = [self.namer classNameForExample:example]; NSString *methodName = [self.namer methodNameForExample:example]; self.currentMethodName = methodName; [self logMessage:[NSString stringWithFormat:@"Test Case '-[%@ %@]' started.", testSuite, methodName]]; } } - (void)runDidFinishExample:(CDRExample *)example { if ([self shouldReportExample:example]) { NSString *testSuite = [self.namer classNameForExample:example]; NSString *status = [self stateNameForExample:example]; [self logMessage:[self stringForErrorsForExample:example suiteName:testSuite caseName:self.currentMethodName]]; [self logMessage:[NSString stringWithFormat:@"Test Case '-[%@ %@]' %@ (%.3f seconds).\n", testSuite, self.currentMethodName, status, example.runTime]]; } } - (void)runWillStartSpec:(CDRSpec *)spec { if ([self shouldReportSpec:spec]) { [self startSuite:NSStringFromClass([spec class]) atDate:[NSDate date]]; } } - (void)runDidFinishSpec:(CDRSpec *)spec { if ([self shouldReportSpec:spec]) { [self finishSuite:NSStringFromClass([spec class]) atDate:[NSDate date]]; [self printStatsForExamples:@[spec.rootGroup]]; } } #pragma mark - Protected - (void)logMessage:(NSString *)message { fprintf(stderr, "%s\n", message.UTF8String); } #pragma mark - Private - (BOOL)isFocused { return [CDRSpecHelper specHelper].shouldOnlyRunFocused; } - (NSString *)rootSuiteName { return [self isFocused] ? @"Multiple Selected Tests" : @"All tests"; } - (BOOL)shouldReportExample:(CDRExample *)example { BOOL isNotSkippedOrPending = !example.shouldRun || !example.isPending; return isNotSkippedOrPending && (![self isFocused] || example.isFocused); } - (BOOL)shouldReportSpec:(CDRSpec *)spec { return ![self isFocused] || spec.rootGroup.hasFocusedExamples; } - (NSString *)bundleSuiteName { NSBundle *testBundle = CDRBundleContainingSpecs(); return testBundle.bundleURL.pathComponents.lastObject; } - (void)startSuite:(NSString *)name atDate:(NSDate *)date { NSString *format = [self.formatter stringFromDate:date]; [self logMessage:[NSString stringWithFormat:@"Test Suite '%@' started at %@.", name, format]]; } - (void)finishSuite:(NSString *)name atDate:(NSDate *)date { NSString *format = [self.formatter stringFromDate:date]; [self logMessage:[NSString stringWithFormat:@"Test Suite '%@' finished at %@.", name, format]]; } - (NSString *)stateNameForExample:(CDRExample *)example { switch (example.state) { case CDRExampleStatePassed: return @"passed"; case CDRExampleStateFailed: case CDRExampleStateError: return @"failed"; case CDRExampleStatePending: case CDRExampleStateSkipped: case CDRExampleStateIncomplete: return nil; } } - (NSString *)stringForErrorsForExample:(CDRExample *)example suiteName:(NSString *)suiteName caseName:(NSString *)caseName { if (example.failure) { NSString *errorDescription = [example.failure.reason stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; NSString *errorMessage = [NSString stringWithFormat:@"%@:%d: error: -[%@ %@] : %@", example.failure.fileName, example.failure.lineNumber, suiteName, caseName, errorDescription]; return errorMessage; } else { return @""; } } - (void)printStatsForExamples:(NSArray *)examples { NSDictionary *stats = [self statsForExamples:examples]; NSUInteger count = [[stats objectForKey:@"count"] unsignedIntegerValue]; NSUInteger failed = [[stats objectForKey:@"failed"] unsignedIntegerValue]; NSUInteger unexpected = [[stats objectForKey:@"unexpected"] unsignedIntegerValue]; const char *testsString = (count == 1 ? "test" : "tests"); const char *failuresString = (failed == 1 ? "failure" : "failures"); float totalTimeElapsed = [self.endTime timeIntervalSinceDate:self.startTime]; [self logMessage:[NSString stringWithFormat: @"Executed %lu %s, with %lu %s (%lu unexpected) in %.4f (%.4f) seconds", (unsigned long)count, testsString, (unsigned long)failed, failuresString, (unsigned long)unexpected, totalTimeElapsed, totalTimeElapsed]]; } - (NSDictionary *)statsForExamples:(NSArray *)examples { NSUInteger count = 0; NSUInteger unexpected = 0; NSUInteger failed = 0; for (id example in examples) { if (![example hasChildren]) { if (![example isKindOfClass:[CDRExampleGroup class]]) { count += ([self stateNameForExample:example] != nil); CDRExampleState state = ((CDRExample *)example).state; unexpected += (state == CDRExampleStateError); failed += (state == CDRExampleStateFailed); } } else { NSDictionary *stats = [self statsForExamples:[example examples]]; count += [[stats objectForKey:@"count"] unsignedIntegerValue]; unexpected += [[stats objectForKey:@"unexpected"] unsignedIntegerValue]; failed += [[stats objectForKey:@"failed"] unsignedIntegerValue]; } } return [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithUnsignedInteger:count], @"count", [NSNumber numberWithUnsignedInteger:unexpected], @"unexpected", [NSNumber numberWithUnsignedInteger:failed], @"failed", nil]; } @end ================================================ FILE: Source/Reporters/CDRReportDispatcher.m ================================================ #import "CDRReportDispatcher.h" #import "CDRExampleGroup.h" @interface CDRReportDispatcher () @property (strong, nonatomic) CDRSpec *currentSpec; @end @implementation CDRReportDispatcher @synthesize currentSpec = currentSpec_; + (instancetype)dispatcherWithReporters:(NSArray *)reporters { return [[[self alloc] initWithReporters:reporters] autorelease]; } - (void)dealloc { [reporters_ release]; reporters_ = nil; self.currentSpec = nil; [super dealloc]; } - (id)init { [self doesNotRecognizeSelector:_cmd]; return nil; } - (id)initWithReporters:(NSArray *)reporters { self = [super init]; if (self) { reporters_ = [reporters copy]; } return self; } #pragma mark - Public - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed { for (id reporter in reporters_) { [reporter runWillStartWithGroups:groups andRandomSeed:seed]; } } - (void)runDidComplete { [self setCurrentSpecAndNotifyIfNeeded:nil]; for (id reporter in reporters_) { [reporter runDidComplete]; } } - (int)result { int result = 0; for (id reporter in reporters_) { result |= [reporter result]; } return result; } - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup { [self setCurrentSpecAndNotifyIfNeeded:exampleGroup.spec]; for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runWillStartExampleGroup:)]) { [reporter runWillStartExampleGroup:exampleGroup]; } } } - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup { [self setCurrentSpecAndNotifyIfNeeded:exampleGroup.spec]; for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runDidFinishExampleGroup:)]) { [reporter runDidFinishExampleGroup:exampleGroup]; } } } - (void)runWillStartExample:(CDRExample *)example { for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runWillStartExample:)]) { [reporter runWillStartExample:example]; } } } - (void)runDidFinishExample:(CDRExample *)example { for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runDidFinishExample:)]) { [reporter runDidFinishExample:example]; } } } - (void)runWillStartSpec:(CDRSpec *)spec { for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runWillStartSpec:)]) { [reporter runWillStartSpec:spec]; } } } - (void)runDidFinishSpec:(CDRSpec *)spec { for (id reporter in reporters_) { if ([reporter respondsToSelector:@selector(runDidFinishSpec:)]) { [reporter runDidFinishSpec:spec]; } } } #pragma mark - Private Properties - (void)setCurrentSpecAndNotifyIfNeeded:(CDRSpec *)currentSpec { if (currentSpec == self.currentSpec) { return; } if (self.currentSpec) { [self runDidFinishSpec:self.currentSpec]; } self.currentSpec = currentSpec; if (currentSpec) { [self runWillStartSpec:self.currentSpec]; } } @end ================================================ FILE: Source/Reporters/CDRTeamCityReporter.m ================================================ //For information on TeamCity messages see: http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity #import "CDRTeamCityReporter.h" #import "CDRExample.h" #import "CDRExampleGroup.h" @implementation CDRTeamCityReporter - (NSString *)escapeText:(NSString *)text { NSString *tmp = text; tmp = [text stringByReplacingOccurrencesOfString:@"|" withString:@"||"]; tmp = [tmp stringByReplacingOccurrencesOfString:@"'" withString:@"|'"]; tmp = [tmp stringByReplacingOccurrencesOfString:@"\n" withString:@"|n"]; tmp = [tmp stringByReplacingOccurrencesOfString:@"\r" withString:@"|r"]; tmp = [tmp stringByReplacingOccurrencesOfString:@"[" withString:@"|["]; tmp = [tmp stringByReplacingOccurrencesOfString:@"]" withString:@"|]"]; return tmp; } - (NSString *)startedMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"##teamcity[testStarted name='%@']", [self escapeText:example.fullText]]; } - (NSString *)finishedMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"##teamcity[testFinished name='%@']", [self escapeText:example.fullText]]; } - (NSString *)pendingMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]]; } - (NSString *)skippedMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]]; } - (NSString *)failureMessageForExample:(CDRExample *)example { return [NSString stringWithFormat:@"##teamcity[testFailed name='%@' message='%@']", [self escapeText:example.fullText], [self escapeText:example.message]]; } - (void)reportOnExample:(CDRExample *)example { switch (example.state) { case CDRExampleStatePassed: printf("%s\n%s\n", [[self startedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding], [[self finishedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]); break; case CDRExampleStatePending: printf("%s\n", [[self pendingMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]); [pendingMessages_ addObject:[super pendingMessageForExample:example]]; break; case CDRExampleStateSkipped: printf("%s\n", [[self skippedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]); [skippedMessages_ addObject:[super skippedMessageForExample:example]]; break; case CDRExampleStateError: case CDRExampleStateFailed: printf("%s\n%s\n%s\n", [[self startedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding], [[self failureMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding], [[self finishedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]); [failureMessages_ addObject:[super failureMessageForExample:example]]; break; default: break; } } @end ================================================ FILE: Source/XCTest/CDRSpec+XCTestSupport.m ================================================ #import #import "CDRReportDispatcher.h" #import "CDRSpec.h" #import "CDRExampleGroup.h" #import "CDRExample.h" #import "CDROTestNamer.h" #import "CDRRuntimeUtilities.h" #import "CDRFunctions.h" #import "CDRSymbolicator.h" #import "CDRXCTestCase.h" #import "NSInvocation+CDRXExample.h" const char *CDRXSpecKey; #pragma mark - XCTest forward declarations @interface CDR_XCTestSuite : NSObject - (id)testSuiteWithName:(NSString *)name; - (id)defaultTestSuite; - (void)addTest:(id)test; @end #pragma mark - SenTestingKit forward declarations @interface CDR_SenTestSuite : NSObject - (void)failWithException:(NSException *)anException; @end @interface NSException (SenTestFailure) + (NSException *) failureInFile:(NSString *) filename atLine:(int) lineNumber withDescription:(NSString *) formatString, ...; @end #pragma mark - CDRSpec XCTest support @implementation CDRSpec (XCTestSupport) #pragma mark - Public - (id)testSuiteWithRandomSeed:(unsigned int)seed dispatcher:(CDRReportDispatcher *)dispatcher { NSString *className = NSStringFromClass([self class]); Class testSuiteClass = NSClassFromString(@"XCTestSuite") ?: NSClassFromString(@"SenTestSuite"); id testSuite = [(id)testSuiteClass testSuiteWithName:className]; Class newXCTestSubclass = [self createTestCaseSubclass]; CDROTestNamer *namer = [[[CDROTestNamer alloc] init] autorelease]; NSArray *examples = [self allExamplesToRun]; NSMutableArray *testInvocations = [NSMutableArray array]; NSMutableArray *unusedPendingExamples = [NSMutableArray array]; for (CDRExample *example in examples) { if (example.isPending) { if (testInvocations.count > 0) { [[testInvocations lastObject] cdr_addSupplementaryExample:example]; } else { [unusedPendingExamples addObject:example]; } } else { NSString *methodName = [namer methodNameForExample:example withClassName:NSStringFromClass([self class])]; SEL selector = NSSelectorFromString(methodName); NSMethodSignature *methodSignature = [newXCTestSubclass instanceMethodSignatureForSelector:selector]; if (!methodSignature) { [self createTestMethodForSelector:selector onClass:newXCTestSubclass]; methodSignature = [newXCTestSubclass instanceMethodSignatureForSelector:selector]; } NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; invocation.selector = selector; invocation.cdr_dispatcher = dispatcher; invocation.cdr_examples = [unusedPendingExamples arrayByAddingObject:example]; invocation.cdr_specClassName = className; [testInvocations addObject:invocation]; [unusedPendingExamples removeAllObjects]; } } // save the spec to prevent premature deallocation objc_setAssociatedObject(testSuite, &CDRXSpecKey, self, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [(id)newXCTestSubclass setTestInvocations:CDRShuffleItemsInArrayWithSeed(testInvocations, seed)]; id defaultTestSuite = [(id)newXCTestSubclass defaultTestSuite]; for (id test in [defaultTestSuite valueForKey:@"tests"]) { [testSuite addTest:test]; } return testSuite; } #pragma mark - Private - (Class)createTestCaseSubclass { NSString *className = NSStringFromClass([self class]); Class testCaseClass = NSClassFromString(@"XCTestCase") ?: NSClassFromString(@"SenTestCase"); NSString *newClassName = [NSString stringWithFormat:@"_%@", className]; Class newXCTestSubclass = NSClassFromString(newClassName); if (!newXCTestSubclass) { newXCTestSubclass = [CDRRuntimeUtilities createMixinSubclassOf:testCaseClass newClassName:newClassName templateClass:[CDRXCTestCase class]]; } return newXCTestSubclass; } - (NSArray *)allExamplesToRun { NSMutableArray *examples = [NSMutableArray array]; NSMutableArray *groupsQueue = [NSMutableArray arrayWithArray:self.rootGroup.examples]; while (groupsQueue.count) { CDRExampleBase *exampleBase = [groupsQueue objectAtIndex:0]; [groupsQueue removeObjectAtIndex:0]; if (exampleBase.hasChildren) { [groupsQueue addObjectsFromArray:[(CDRExampleGroup *)exampleBase examples]]; } else if ([exampleBase shouldRun]) { [examples addObject:exampleBase]; } } return examples; } static void testMethodImplementation(id instance, SEL _cmd) { NSMutableSet *alreadyReportedExampleGroups = [NSMutableSet set]; CDRReportDispatcher *theDispatcher = [[instance invocation] cdr_dispatcher]; for (CDRExample *example in [[instance invocation] cdr_examples]) { CDRExampleGroup *parentGroup = (CDRExampleGroup *)example.parent; while (![parentGroup isEqual:example.spec.rootGroup]) { if (![alreadyReportedExampleGroups containsObject:parentGroup]) { [theDispatcher runWillStartExampleGroup:parentGroup]; } parentGroup = (CDRExampleGroup *)[parentGroup parent]; } [example runWithDispatcher:theDispatcher]; if (example.failure) { if ([instance respondsToSelector:@selector(recordFailureWithDescription:inFile:atLine:expected:)]) { [instance recordFailureWithDescription:example.failure.reason inFile:example.failure.fileName atLine:example.failure.lineNumber expected:YES]; } else { [instance failWithException:[NSException failureInFile:example.failure.fileName atLine:example.failure.lineNumber withDescription:example.failure.description]]; } } parentGroup = (CDRExampleGroup *)example.parent; while (![parentGroup isEqual:example.spec.rootGroup]) { if (![alreadyReportedExampleGroups containsObject:parentGroup]) { [theDispatcher runDidFinishExampleGroup:parentGroup]; [alreadyReportedExampleGroups addObject:parentGroup]; } parentGroup = (CDRExampleGroup *)[parentGroup parent]; } } } - (void)createTestMethodForSelector:(SEL)selector onClass:(Class)aClass { Method m = class_getInstanceMethod([self class], @selector(defineBehaviors)); const char *encoding = method_getTypeEncoding(m); class_addMethod(aClass, selector, (IMP)testMethodImplementation, encoding); } @end ================================================ FILE: Source/XCTest/CDRXCTestCase.m ================================================ #import "CDRXCTestCase.h" #import "CDRExample.h" #import "NSInvocation+CDRXExample.h" #import const char *CDRXTestInvocationsKey; @interface CDRXCTestCase (XCTestCaseMethods) @property (strong) NSInvocation *invocation; // defined by XCTestCase - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected; @end @implementation CDRXCTestCase - (NSString *)name { return [NSString stringWithFormat:@"-[%@ %@]", [self testClassName], [self testMethodName]]; } - (NSString *)testClassName { return [[self invocation] cdr_specClassName]; } - (NSString *)testMethodName { return NSStringFromSelector([[self invocation] selector]); } - (void)invokeTest { NSInvocation *invocation = [self invocation]; invocation.target = self; [invocation invoke]; } + (NSArray *)testInvocations { return objc_getAssociatedObject(self, &CDRXTestInvocationsKey); } + (void)setTestInvocations:(NSArray *)array { objc_setAssociatedObject(self, &CDRXTestInvocationsKey, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } /// This is needed to allow for runtime lookup of the superclass #define super_recordFailure(description, filename, lineNumber, expected) do { \ Class parentClass = class_getSuperclass([self class]); \ IMP superPerformTest = class_getMethodImplementation(parentClass, @selector(recordFailureWithDescription:inFile:atLine:expected:)); \ ((void (*)(id instance, SEL cmd, NSString *, NSString *, NSUInteger, BOOL))superPerformTest)(self, _cmd, description, filename, lineNumber, expected); \ } while(0); - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected { CDRExample *example = self.invocation.cdr_examples.firstObject; if (example.state == CDRExampleStateIncomplete) { [[CDRSpecFailure specFailureWithReason:description fileName:filename lineNumber:(int)lineNumber] raise]; } else { super_recordFailure(description, filename, lineNumber, expected); } } @end ================================================ FILE: Source/XCTest/CDRXCTestFunctions.m ================================================ #import #import #import "CDRFunctions.h" #import "CDRPrivateFunctions.h" #import "CDRXCTestSuite.h" #import "CDRRuntimeUtilities.h" #import "CDRXCTestObserver.h" #import "CDRReportDispatcher.h" #import "CDRSpec.h" #import "CDRSpecRun.h" #import "CDRStateTracker.h" id CDRCreateXCTestSuite() { Class testSuiteClass = NSClassFromString(@"XCTestSuite") ?: NSClassFromString(@"SenTestSuite"); Class testSuiteSubclass = NSClassFromString(@"_CDRXCTestSuite"); if (testSuiteSubclass == nil) { testSuiteSubclass = [CDRRuntimeUtilities createMixinSubclassOf:testSuiteClass newClassName:@"_CDRXCTestSuite" templateClass:[CDRXCTestSuite class]]; } CDRStateTracker *stateTracker = [[[CDRStateTracker alloc] init] autorelease]; CDRSpecRun *run = [[[CDRSpecRun alloc] initWithStateTracker:stateTracker exampleReporters:CDRReportersToRun()] autorelease]; return [[[testSuiteSubclass alloc] initWithSpecRun:run] autorelease]; } void CDRAddCedarTestObserver(id observationCenter) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [observationCenter CDR_original_addTestObserver:[[CDRXCTestObserver alloc] init]]; }); } void CDRSwizzleTestSuiteAllTestsMethod() { Class testSuiteClass = NSClassFromString(@"XCTestSuite") ?: NSClassFromString(@"SenTestSuite"); if (!testSuiteClass) { [[NSException exceptionWithName:@"CedarNoTestFrameworkAvailable" reason:@"You must link against either the XCTest or SenTestingKit frameworks." userInfo:nil] raise]; } Class testSuiteMetaClass = object_getClass(testSuiteClass); Method m = class_getClassMethod(testSuiteClass, @selector(allTests)); class_addMethod(testSuiteMetaClass, @selector(CDR_original_allTests), method_getImplementation(m), method_getTypeEncoding(m)); IMP newImp = imp_implementationWithBlock(^id(id self){ id defaultSuite = [self CDR_original_allTests]; [defaultSuite addTest:CDRCreateXCTestSuite()]; return defaultSuite; }); class_replaceMethod(testSuiteMetaClass, @selector(allTests), newImp, method_getTypeEncoding(m)); } void CDRSwizzleTestObservationCenter() { Class observationCenterClass = NSClassFromString(@"XCTestObservationCenter"); if (observationCenterClass && [observationCenterClass respondsToSelector:@selector(sharedTestObservationCenter)]) { // Swizzle -addTestObserver: Method addTestObserverMethod = class_getInstanceMethod(observationCenterClass, @selector(addTestObserver:)); class_addMethod(observationCenterClass, @selector(CDR_original_addTestObserver:), method_getImplementation(addTestObserverMethod), method_getTypeEncoding(addTestObserverMethod)); IMP newAddTestObserverImp = imp_implementationWithBlock(^void(id self, id observer){ [self CDR_original_addTestObserver:observer]; CDRAddCedarTestObserver(self); }); class_replaceMethod(observationCenterClass, @selector(addTestObserver:), newAddTestObserverImp, method_getTypeEncoding(addTestObserverMethod)); // Swizzle -_addLegacyTestObserver: Method addLegacyTestObserverMethod = class_getInstanceMethod(observationCenterClass, @selector(_addLegacyTestObserver:)); if (addLegacyTestObserverMethod) { class_addMethod(observationCenterClass, @selector(CDR_original__addLegacyTestObserver:), method_getImplementation(addLegacyTestObserverMethod), method_getTypeEncoding(addLegacyTestObserverMethod)); IMP newAddLegacyTestObserverImp = imp_implementationWithBlock(^void(id self, id observer){ [self CDR_original__addLegacyTestObserver:observer]; CDRAddCedarTestObserver(self); }); class_replaceMethod(observationCenterClass, @selector(_addLegacyTestObserver:), newAddLegacyTestObserverImp, method_getTypeEncoding(addLegacyTestObserverMethod)); } } } void CDRInjectIntoXCTestRunner() { CDRSwizzleTestSuiteAllTestsMethod(); CDRSwizzleTestObservationCenter(); } ================================================ FILE: Source/XCTest/CDRXCTestObserver.m ================================================ #import "CDRXCTestObserver.h" #import "CDRFunctions.h" #import "CDRPrivateFunctions.h" @interface CDRXCTestObserver () @property (assign) BOOL observedTestSuiteStart; @end @implementation CDRXCTestObserver - (void)testSuiteWillStart:(XCTestSuite *)testSuite { if (self.observedTestSuiteStart) { return; } self.observedTestSuiteStart = YES; id cedarTestSuite = CDRCreateXCTestSuite(); [testSuite addTest:cedarTestSuite]; } @end ================================================ FILE: Source/XCTest/CDRXCTestSuite.m ================================================ #import "CDRXCTestSuite.h" #import "CDRSpecRun.h" #import "CDRSpec.h" #import "CDRXCTestSupport.h" #import const char *CDRSpecRunKey; @interface CDRXCTestSuite (FromXCTest) - (instancetype)initWithName:(NSString *)name; - (void)addTest:(id)test; @end @interface CDRXCTestSuite () @property (nonatomic, retain) CDRSpecRun *specRun; @end @implementation CDRXCTestSuite - (instancetype)initWithSpecRun:(CDRSpecRun *)specRun { if (self = [self initWithName:@"Cedar"]) { self.specRun = specRun; for (CDRSpec *spec in specRun.specs) { [self addTest:[spec testSuiteWithRandomSeed:specRun.seed dispatcher:specRun.dispatcher]]; } } return self; } /// This is needed to allow for runtime lookup of the superclass #define super_performTest(RUN) do { \ Class parentClass = class_getSuperclass([self class]); \ IMP superPerformTest = class_getMethodImplementation(parentClass, @selector(performTest:)); \ ((void (*)(id instance, SEL cmd, id run))superPerformTest)(self, _cmd, RUN); \ } while(0); - (void)performTest:(id)aRun { [self.specRun performSpecRun:^{ super_performTest(aRun); }]; } #pragma mark - Accessors - (void)setSpecRun:(CDRSpecRun *)specRun { objc_setAssociatedObject(self, &CDRSpecRunKey, specRun, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (CDRSpecRun *)specRun { return objc_getAssociatedObject(self, &CDRSpecRunKey); } @end ================================================ FILE: Source/XCTest/NSInvocation+CDRXExample.m ================================================ #import "NSInvocation+CDRXExample.h" #import const char *CDRXDispatcherKey; const char *CDRXExamplesKey; const char *CDRXSpecClassNameKey; @implementation NSInvocation (CDRXExample) - (CDRReportDispatcher *)cdr_dispatcher { return objc_getAssociatedObject(self, &CDRXDispatcherKey); } - (void)cdr_setDispatcher:(CDRReportDispatcher *)dispatcher { objc_setAssociatedObject(self, &CDRXDispatcherKey, dispatcher, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSArray *)cdr_examples { return objc_getAssociatedObject(self, &CDRXExamplesKey); } - (void)cdr_setExamples:(NSArray *)examples { objc_setAssociatedObject(self, &CDRXExamplesKey, examples, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSString *)cdr_specClassName { return objc_getAssociatedObject(self, &CDRXSpecClassNameKey); } - (void)cdr_setSpecClassName:(NSString *)specClassName { objc_setAssociatedObject(self, &CDRXSpecClassNameKey, specClassName, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (void)cdr_addSupplementaryExample:(CDRExample *)example { NSArray *existingExamples = self.cdr_examples ?: @[]; self.cdr_examples = [existingExamples arrayByAddingObject:example]; } @end ================================================ FILE: Source/iOS/CedarApplicationDelegate.m ================================================ #import "CedarApplicationDelegate.h" #import "CDRFunctions.h" @implementation CedarApplication - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { exit(CDRRunSpecs()); return NO; } @end @implementation CedarApplicationDelegate - (id)init { if (self = [super init]) { CDRSuppressStandardPipesWhileLoadingClasses(); } return self; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { exit(CDRRunSpecs()); return NO; } - (UIWindow *)window { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"This Cedar iOS spec suite is run with the CedarApplicationDelegate. If your code needs the UIApplicationDelegate's window, you should stub this method to return an appropriate window." userInfo:nil]; } @end ================================================ FILE: Source/iOS/NSBundle+MainBundleHijack.m ================================================ #import #import "CDRFunctions.h" #import @implementation NSBundle (MainBundleHijack) static NSBundle *mainBundle__ = nil; NSBundle *CDRMainBundle(id self, SEL _cmd) { return mainBundle__; } + (void)load { CDRSuppressStandardPipesWhileLoadingClasses(); NSString *extension = CDRGetTestBundleExtension(); if (!extension) { return; } BOOL mainBundleIsApp = [[[NSBundle mainBundle] bundlePath] hasSuffix:@".app"]; BOOL mainBundleIsTestBundle = [[[NSBundle mainBundle] bundlePath] hasSuffix:extension]; if (!mainBundleIsApp && !mainBundleIsTestBundle) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; for (NSBundle *bundle in [NSBundle allBundles]) { if ([[bundle bundlePath] hasSuffix:extension]) { mainBundle__ = [bundle retain]; Class nsBundleMetaClass = objc_getMetaClass("NSBundle"); class_replaceMethod(nsBundleMetaClass, @selector(mainBundle), (IMP)CDRMainBundle, "v@:"); } } [pool drain]; } } @end ================================================ FILE: Spec/CDRExampleGroupSpec.mm ================================================ #import "Cedar.h" #import "SimpleKeyValueObserver.h" #import "FibonacciCalculator.h" #import "CDRReportDispatcher.h" #import using namespace Cedar::Matchers; using namespace Cedar::Doubles; extern void (^runInFocusedSpecsMode)(CDRExampleBase *, CDRReportDispatcher *); SPEC_BEGIN(CDRExampleGroupSpec) describe(@"CDRExampleGroup", ^{ __block CDRExampleGroup *group; __block CDRExample *incompleteExample, *pendingExample, *passingExample, *failingExample, *errorExample, *nonFocusedExample; __block CDRReportDispatcher *dispatcher; NSString *groupText = @"Group!"; beforeEach(^{ dispatcher = nice_fake_for([CDRReportDispatcher class]); group = [[[CDRExampleGroup alloc] initWithText:groupText] autorelease]; incompleteExample = [[[CDRExample alloc] initWithText:@"incomplete" andBlock:^{}] autorelease]; passingExample = [[[CDRExample alloc] initWithText:@"I should pass" andBlock:^{}] autorelease]; failingExample = [[[CDRExample alloc] initWithText:@"I should fail" andBlock:^{fail(@"I have failed.");}] autorelease]; pendingExample = [[[CDRExample alloc] initWithText:@"I should pend" andBlock:nil] autorelease]; errorExample = [[[CDRExample alloc] initWithText:@"I should raise an error" andBlock:^{ @throw @"wibble"; }] autorelease]; nonFocusedExample = [[[CDRExample alloc] initWithText:@"I should not be focused" andBlock:^{}] autorelease]; }); describe(@"runWithDispatcher:", ^{ beforeEach(^{ [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should tell the reporter the example group is about to start", ^{ dispatcher should have_received(@selector(runWillStartExampleGroup:)).with(group); }); it(@"should report each executed example in the group", ^{ dispatcher should have_received(@selector(runWillStartExample:)).with(passingExample); dispatcher should have_received(@selector(runDidFinishExample:)).with(passingExample); }); it(@"should tell the reporter when the group has finished", ^{ dispatcher should have_received(@selector(runDidFinishExampleGroup:)).with(group); }); describe(@"running it a second time", ^{ it(@"should fail", ^{ ^{ [group runWithDispatcher:dispatcher]; } should raise_exception.with_reason([NSString stringWithFormat:@"Attempt to run example group twice: %@", [group fullText]]); }); }); describe(@"releasing objects captured in spec blocks", ^{ __block id weakCapturedObject; beforeEach(^{ group = [[[CDRExampleGroup alloc] initWithText:groupText] autorelease]; NSString *capturedObject = [@"abc" mutableCopy]; objc_storeWeak(&weakCapturedObject, capturedObject); [group addBefore:^{ [capturedObject length]; }]; [group addAfter:^{ [capturedObject length]; }]; group.subjectActionBlock = ^{ [capturedObject length]; }; [capturedObject release]; capturedObject = nil; @autoreleasepool { objc_loadWeak(&weakCapturedObject) should_not be_nil; } [group runWithDispatcher:dispatcher]; }); it(@"should allow captured objects to be deallocated once it has finished running", ^{ objc_loadWeak(&weakCapturedObject) should be_nil; }); }); }); describe(@"hasChildren", ^{ describe(@"for an empty group", ^{ beforeEach(^{ NSUInteger count = group.examples.count; expect(count).to(equal(0)); }); it(@"should return false", ^{ BOOL hasChildren = group.hasChildren; expect(hasChildren).to_not(be_truthy()); }); }); describe(@"for a non-empty group", ^{ beforeEach(^{ [group add:incompleteExample]; NSUInteger count = group.examples.count; expect(count).to_not(equal(0)); }); it(@"should return true", ^{ BOOL hasChildren = group.hasChildren; expect(hasChildren).to(be_truthy()); }); }); }); describe(@"isFocused", ^{ it(@"should return false by default", ^{ expect([group isFocused]).to_not(be_truthy()); }); it(@"should return false when group is not focused", ^{ group.focused = NO; expect([group isFocused]).to_not(be_truthy()); }); it(@"should return true when group is focused", ^{ group.focused = YES; expect([group isFocused]).to(be_truthy()); }); }); describe(@"hasFocusedExamples", ^{ context(@"for a group that is focused", ^{ beforeEach(^{ group.focused = YES; }); it(@"should return true", ^{ expect([group hasFocusedExamples]).to(be_truthy()); }); }); context(@"for a group that is not focused", ^{ beforeEach(^{ expect([group isFocused]).to_not(be_truthy()); }); it(@"should return false", ^{ expect([group hasFocusedExamples]).to_not(be_truthy()); }); context(@"and has at least one focused example", ^{ beforeEach(^{ [group add:failingExample]; [group add:passingExample]; passingExample.focused = YES; }); it(@"should return true", ^{ expect([group hasFocusedExamples]).to(be_truthy()); }); }); context(@"and has at least one focused group", ^{ beforeEach(^{ CDRExampleGroup *innerGroup = [[CDRExampleGroup alloc] initWithText:@"Inner group"]; innerGroup.focused = YES; [group add:innerGroup]; CDRExampleGroup *anotherInnerGroup = [[CDRExampleGroup alloc] initWithText:@"Another inner group"]; [group add:anotherInnerGroup]; [innerGroup release]; [anotherInnerGroup release]; }); it(@"should return true", ^{ expect([group hasFocusedExamples]).to(be_truthy()); }); }); }); }); describe(@"afterEach", ^{ __block NSInteger blockInvocationCount; beforeEach(^{ blockInvocationCount = 0; CDRSpecBlock afterEachBlock = ^{ ++blockInvocationCount; }; [group addAfter:afterEachBlock]; [group add:errorExample]; [group add:failingExample]; [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be called after each example runs, regardless of failures or errors", ^{ blockInvocationCount should equal(3); }); }); describe(@"state", ^{ describe(@"for a group containing no examples", ^{ beforeEach(^{ NSUInteger count = group.examples.count; expect(count).to(equal(0)); }); it(@"should be CDRExampleStatePending", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStatePending)); }); }); describe(@"for a group containing at least one incomplete example", ^{ beforeEach(^{ [group add:incompleteExample]; }); it(@"should be CDRExampleStateIncomplete", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStateIncomplete)); }); }); describe(@"for a group containing only complete examples", ^{ describe(@"with only passing examples", ^{ beforeEach(^{ [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStatePassed", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStatePassed)); }); }); describe(@"with only failing examples", ^{ beforeEach(^{ [group add:failingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateFailed", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStateFailed)); }); }); describe(@"with only pending examples", ^{ beforeEach(^{ [group add:pendingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStatePending", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStatePending)); }); }); describe(@"with only skipped examples", ^{ beforeEach(^{ [group add:passingExample]; passingExample.focused = NO; runInFocusedSpecsMode(group, dispatcher); }); it(@"should be CDRExampleStateSkipped", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStateSkipped)); }); }); describe(@"with only error examples", ^{ beforeEach(^{ [group add:errorExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStateError)); }); }); describe(@"with at least one passing example", ^{ beforeEach(^{ [group add:passingExample]; }); describe(@"with at least one skipped example", ^{ beforeEach(^{ passingExample.focused = YES; [group add:nonFocusedExample]; runInFocusedSpecsMode(group, dispatcher); }); it(@"should be CDRExampleStatePassed", ^{ expect([group state]).to(equal(CDRExampleStatePassed)); }); }); }); describe(@"with at least one pending example", ^{ beforeEach(^{ [group add:pendingExample]; }); describe(@"with all other examples passing", ^{ beforeEach(^{ [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStatePending", ^{ expect([group state]).to(equal(CDRExampleStatePending)); }); }); describe(@"with at least one skipped example", ^{ beforeEach(^{ pendingExample.focused = YES; [group add:nonFocusedExample]; runInFocusedSpecsMode(group, dispatcher); }); it(@"should be CDRExampleStatePending", ^{ CDRExampleState state = group.state; expect(state).to(equal(CDRExampleStatePending)); }); }); }); describe(@"with at least one failing example", ^{ beforeEach(^{ [group add:failingExample]; }); describe(@"with all other examples passing", ^{ beforeEach(^{ [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateFailed", ^{ expect([group state]).to(equal(CDRExampleStateFailed)); }); }); describe(@"with at least one pending example", ^{ beforeEach(^{ [group add:pendingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateFailed", ^{ expect([group state]).to(equal(CDRExampleStateFailed)); }); }); describe(@"with at least one skipped example", ^{ beforeEach(^{ failingExample.focused = YES; [group add:passingExample]; runInFocusedSpecsMode(group, dispatcher); }); it(@"should be CDRExampleStateFailed", ^{ expect([group state]).to(equal(CDRExampleStateFailed)); }); }); }); describe(@"with at least one error example", ^{ beforeEach(^{ [group add:errorExample]; }); describe(@"with all other examples passing", ^{ beforeEach(^{ [group add:passingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ expect([group state]).to(equal(CDRExampleStateError)); }); }); describe(@"with at least one failing example", ^{ beforeEach(^{ [group add:failingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ expect([group state]).to(equal(CDRExampleStateError)); }); }); describe(@"with at least one pending example", ^{ beforeEach(^{ [group add:pendingExample]; [group runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ expect([group state]).to(equal(CDRExampleStateError)); }); }); describe(@"with at least one skipped example", ^{ beforeEach(^{ errorExample.focused = YES; [group add:nonFocusedExample]; runInFocusedSpecsMode(group, dispatcher); }); it(@"should be CDRExampleStateError", ^{ expect([group state]).to(equal(CDRExampleStateError)); }); }); }); }); describe(@"with an afterEach that raises an exception", ^{ __block CDRExample *passingExample2; __block CDRExample *failingExample2; beforeEach(^{ CDRSpecBlock afterEachBlock = ^{ [[NSException exceptionWithName:@"Exception in afterEach" reason:@"afterEach exception - test execution should continue" userInfo:nil] raise]; }; [group addAfter:afterEachBlock]; [group add:passingExample]; [group add:failingExample]; CDRExampleGroup *childGroup = [[[CDRExampleGroup alloc] initWithText:@"child group" isRoot:NO] autorelease]; passingExample2 = [[[CDRExample alloc] initWithText:@"I should pass" andBlock:^{}] autorelease]; failingExample2 = [[[CDRExample alloc] initWithText:@"I should fail" andBlock:^{fail(@"I have failed.");}] autorelease]; [childGroup add:passingExample2]; [childGroup add:failingExample2]; [group add:childGroup]; [group runWithDispatcher:dispatcher]; }); it(@"should mark all passing examples be CDRExampleStateError", ^{ passingExample.state should equal(CDRExampleStateError); passingExample2.state should equal(CDRExampleStateError); }); it(@"should leave examples that have already failed alone", ^{ failingExample.state should equal(CDRExampleStateFailed); failingExample2.state should equal(CDRExampleStateFailed); }); }); describe(@"KVO", ^{ __block id mockObserver; beforeEach(^{ mockObserver = [[[SimpleKeyValueObserver alloc] init] autorelease]; spy_on(mockObserver); }); describe(@"when a child changes state, causing the group to change state", ^{ beforeEach(^{ [group add:passingExample]; }); it(@"should report that the state has changed", ^{ [group addObserver:mockObserver forKeyPath:@"state" options:0 context:NULL]; [group runWithDispatcher:dispatcher]; [group removeObserver:mockObserver forKeyPath:@"state"]; mockObserver should have_received("observeValueForKeyPath:ofObject:change:context:"); }); }); describe(@"when a child's child changes state, causing the child group to change state, causing the top-level group to change state", ^{ __block CDRExampleGroup *subgroup; beforeEach(^{ subgroup = [[CDRExampleGroup alloc] initWithText:@"subgroup"]; [group add:subgroup]; [subgroup release]; [subgroup add:passingExample]; }); it(@"should report that the state has changed", ^{ [group addObserver:mockObserver forKeyPath:@"state" options:0 context:NULL]; [group runWithDispatcher:dispatcher]; [group removeObserver:mockObserver forKeyPath:@"state"]; mockObserver should have_received("observeValueForKeyPath:ofObject:change:context:"); }); }); }); }); describe(@"progress", ^{ describe(@"when the group is empty", ^{ beforeEach(^{ NSUInteger count = group.examples.count; expect(count).to(equal(0)); }); it(@"should be equal to 1", ^{ float progress = group.progress; expect(progress).to(equal(1)); }); }); describe(@"when the group contains all incomplete children", ^{ beforeEach(^{ [group add:incompleteExample]; }); it(@"should be equal to 0", ^{ float progress = group.progress; expect(progress).to(equal(0)); }); }); describe(@"when the group contains all complete children", ^{ beforeEach(^{ [group add:passingExample]; [passingExample runWithDispatcher:dispatcher]; }); it(@"should be equal to 1", ^{ float progress = group.progress; expect(progress).to(equal(1)); }); }); describe(@"when the group contains a mix of incomplete and complete children", ^{ beforeEach(^{ [group add:incompleteExample]; [group add:passingExample]; [passingExample runWithDispatcher:dispatcher]; [group add:failingExample]; [failingExample runWithDispatcher:dispatcher]; }); it(@"should be the mean of the progress of each child", ^{ float progress = group.progress; expect(progress).to(be_close_to(2.0 / 3.0)); }); }); }); describe(@"message", ^{ it(@"should return an empty string", ^{ NSString *message = group.message; expect(message).to(equal(@"")); }); }); describe(@"hasFullText", ^{ it(@"should return true", ^{ BOOL hasFullText = group.hasFullText; expect(hasFullText).to(equal(YES)); }); describe(@"when initialized normally", ^{ it(@"should return true", ^{ BOOL hasFullText = group.hasFullText; expect(hasFullText).to(equal(YES)); }); }); describe(@"when initialized as a root group", ^{ beforeEach(^{ group = [[[CDRExampleGroup alloc] initWithText:@"I am a root group" isRoot:YES] autorelease]; }); it(@"should return false", ^{ BOOL hasFullText = group.hasFullText; expect(hasFullText).to(equal(NO)); }); }); }); describe(@"fullText/fullTextInPieces", ^{ describe(@"with no parent", ^{ beforeEach(^{ id parent = group.parent; expect(parent).to(be_nil()); }); it(@"should return just its own text", ^{ NSString *fullText = group.fullText; expect(fullText).to(equal(groupText)); }); it(@"should return just its own text in one piece", ^{ NSArray *fullTextPieces = group.fullTextInPieces; expect([fullTextPieces isEqual:[NSArray arrayWithObject:groupText]]).to(be_truthy()); }); }); describe(@"with a parent", ^{ __block CDRExampleGroup *parentGroup; NSString *parentGroupText = @"Parent!"; beforeEach(^{ parentGroup = [[[CDRExampleGroup alloc] initWithText:parentGroupText] autorelease]; [parentGroup add:group]; id parent = group.parent; expect(parent).to_not(be_nil()); }); it(@"should return its parent's text pre-pended with its own text", ^{ NSString *fullText = group.fullText; expect(fullText).to(equal([NSString stringWithFormat:@"%@ %@", parentGroupText, groupText])); }); it(@"should return its parent's text pre-pended with its own text in pieces", ^{ NSArray *fullTextPieces = group.fullTextInPieces; NSArray *expectedPieces = [NSArray arrayWithObjects:parentGroupText, groupText, nil]; expect([fullTextPieces isEqual:expectedPieces]).to(be_truthy()); }); describe(@"when the parent also has a parent", ^{ __block CDRExampleGroup *anotherGroup; NSString *anotherGroupText = @"Another Group!"; beforeEach(^{ anotherGroup = [[[CDRExampleGroup alloc] initWithText:anotherGroupText] autorelease]; [anotherGroup add:parentGroup]; }); it(@"should include the text from all parents, pre-pended in the appopriate order", ^{ NSString *fullText = group.fullText; expect(fullText).to(equal([NSString stringWithFormat:@"%@ %@ %@", anotherGroupText, parentGroupText, groupText])); }); it(@"should include the text from all parents, pre-pended in the appopriate order in pieces", ^{ NSArray *fullTextPieces = group.fullTextInPieces; NSArray *expectedPieces = [NSArray arrayWithObjects:anotherGroupText, parentGroupText, groupText, nil]; expect([fullTextPieces isEqual:expectedPieces]).to(be_truthy()); }); }); }); describe(@"with a root group as a parent", ^{ __block CDRExampleGroup *rootGroup; beforeEach(^{ rootGroup = [[[CDRExampleGroup alloc] initWithText:@"wibble wobble" isRoot:YES] autorelease]; [rootGroup add:group]; id parent = group.parent; expect(parent).to_not(be_nil()); BOOL hasFullText = group.parent.hasFullText; expect(hasFullText).to_not(be_truthy()); }); it(@"should not include its parent's text", ^{ NSString *fullText = group.fullText; NSString *text = group.text; expect(fullText).to(equal(text)); }); it(@"should not include its parent's text in pieces", ^{ NSArray *fullTextPieces = group.fullTextInPieces; NSString *text = group.text; expect([fullTextPieces isEqual:[NSArray arrayWithObject:text]]).to(be_truthy()); }); }); }); describe(@"runTime", ^{ __block CDRExample *firstExample; __block CDRExample *secondExample; __block CDRExampleGroup *exampleGroup; __block BOOL test; beforeEach(^{ test = NO; FibonacciCalculator *calculator = [[[FibonacciCalculator alloc] init] autorelease]; firstExample = [[[CDRExample alloc] initWithText:@"I'm Slow!" andBlock:^{ [calculator computeFibonnaciNumberVeryVerySlowly:4]; }] autorelease]; secondExample = [[[CDRExample alloc] initWithText:@"I'm Slower!" andBlock:^{ [calculator computeFibonnaciNumberVeryVerySlowly:5]; }] autorelease]; exampleGroup = [[[CDRExampleGroup alloc] initWithText:@"I have slow examples"] autorelease]; [exampleGroup add:firstExample]; [exampleGroup add:secondExample]; }); it(@"should return the running time of the test", ^{ exampleGroup.runTime should equal(0); [exampleGroup runWithDispatcher:dispatcher]; exampleGroup.runTime should be_greater_than(0); exampleGroup.runTime should be_greater_than_or_equal_to(firstExample.runTime + secondExample.runTime); }); }); describe(@"subjectActionBlock", ^{ context(@"with a subject action block set", ^{ CDRSpecBlock subjectActionBlock = ^{}; beforeEach(^{ group.subjectActionBlock = subjectActionBlock; }); context(@"and with a parent", ^{ __block CDRExampleGroup *parent; beforeEach(^{ parent = [[[CDRExampleGroup alloc] initWithText:@"Parent"] autorelease]; group.parent = parent; }); context(@"which has a subject action block", ^{ CDRSpecBlock parentsubjectActionBlock = ^{}; beforeEach(^{ parent.subjectActionBlock = parentsubjectActionBlock; }); it(@"should raise a duplicate subject action block exception", ^{ __block id dummy; ^{ dummy = group.subjectActionBlock; } should raise_exception; }); }); context(@"which does not have a subject action block", ^{ beforeEach(^{ parent.subjectActionBlock should_not be_truthy; }); it(@"should return its subject action block", ^{ group.subjectActionBlock should equal(subjectActionBlock); }); }); }); context(@"and with no parent", ^{ beforeEach(^{ group.parent should be_nil; }); it(@"should return its subject action block", ^{ group.subjectActionBlock should equal(subjectActionBlock); }); }); }); context(@"with no subject action block set", ^{ context(@"and with a parent", ^{ __block CDRExampleGroup *parent; beforeEach(^{ parent = [[[CDRExampleGroup alloc] initWithText:@"Parent"] autorelease]; group.parent = parent; }); context(@"which has a subject action block", ^{ CDRSpecBlock parentsubjectActionBlock = ^{}; beforeEach(^{ parent.subjectActionBlock = parentsubjectActionBlock; }); it(@"should return its parent's subject action block", ^{ group.subjectActionBlock should equal(parentsubjectActionBlock); }); }); context(@"which does not have a subject action block", ^{ beforeEach(^{ parent.subjectActionBlock should_not be_truthy; }); it(@"should return nil", ^{ group.subjectActionBlock should_not be_truthy; }); }); }); context(@"and with no parent", ^{ beforeEach(^{ group.parent should be_nil; }); it(@"should return nil", ^{ group.subjectActionBlock should_not be_truthy; }); }); }); }); }); SPEC_END ================================================ FILE: Spec/CDRExampleSpec.mm ================================================ #import #import "Cedar.h" #import "FibonacciCalculator.h" #import "CDRReportDispatcher.h" #import "CedarTestSpecBuilder.h" #import "SimpleKeyValueObserver.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; void (^runInFocusedSpecsMode)(CDRExampleBase *, CDRReportDispatcher *) = ^(CDRExampleBase *example, CDRReportDispatcher *dispatcher) { BOOL before = [CDRSpecHelper specHelper].shouldOnlyRunFocused; [CDRSpecHelper specHelper].shouldOnlyRunFocused = YES; @try { [example runWithDispatcher:dispatcher]; } @finally { [CDRSpecHelper specHelper].shouldOnlyRunFocused = before; } }; SPEC_BEGIN(CDRExampleSpec) typedef void (^CDRSharedExampleBlock)(NSDictionary *context); CDRSharedExampleBlock sharedExampleMethod = [^(NSDictionary *context) { __block CDRExample *example; __block NSString *exampleText; beforeEach(^{ example = [context valueForKey:@"example"]; exampleText = [context valueForKey:@"exampleText"]; }); describe(@"with no parent", ^{ beforeEach(^{ id parent = example.parent; expect(parent).to(be_nil()); }); it(@"should return just its own text", ^{ NSString *fullText = example.fullText; expect(fullText).to(equal(exampleText)); }); it(@"should return just its own text in one piece", ^{ NSArray *fullTextPieces = example.fullTextInPieces; expect([fullTextPieces isEqual:[NSArray arrayWithObject:exampleText]]).to(be_truthy()); }); }); describe(@"with a parent", ^{ __block CDRExampleGroup *group; NSString *groupText = @"Parent!"; beforeEach(^{ group = [[[CDRExampleGroup alloc] initWithText:groupText] autorelease]; [group add:example]; expect(example.parent).to_not(be_nil()); }); it(@"should return its parent's text prepended with its own text", ^{ NSString *fullText = example.fullText; expect(fullText).to(equal([NSString stringWithFormat:@"%@ %@", groupText, exampleText])); }); it(@"should return its parent's text pre-pended with its own text in pieces", ^{ NSArray *fullTextPieces = example.fullTextInPieces; NSArray *expectedPieces = [NSArray arrayWithObjects:groupText, exampleText, nil]; expect([fullTextPieces isEqual:expectedPieces]).to(be_truthy()); }); describe(@"when the parent also has a parent", ^{ __block CDRExampleGroup *rootGroup; NSString *rootGroupText = @"Root!"; beforeEach(^{ rootGroup = [[CDRExampleGroup alloc] initWithText:rootGroupText]; [rootGroup add:group]; }); afterEach(^{ [rootGroup release]; }); it(@"should include the text from all parents, pre-pended in the appropriate order", ^{ NSString *fullText = example.fullText; expect(fullText).to(equal([NSString stringWithFormat:@"%@ %@ %@", rootGroupText, groupText, exampleText])); }); it(@"should include the text from all parents, pre-pended in the appopriate order in pieces", ^{ NSArray *fullTextPieces = example.fullTextInPieces; NSArray *expectedPieces = [NSArray arrayWithObjects:rootGroupText, groupText, exampleText, nil]; expect([fullTextPieces isEqual:expectedPieces]).to(be_truthy()); }); }); }); describe(@"with a root group as a parent", ^{ __block CDRExampleGroup *rootGroup; beforeEach(^{ rootGroup = [[[CDRExampleGroup alloc] initWithText:@"wibble wobble" isRoot:YES] autorelease]; [rootGroup add:example]; expect(example.parent).to_not(be_nil()); BOOL hasFullText = example.parent.hasFullText; expect(hasFullText).to_not(be_truthy()); }); it(@"should not include its parent's text", ^{ expect(example.fullText).to(equal(example.text)); }); it(@"should not include its parent's text in pieces", ^{ NSArray *fullTextPieces = example.fullTextInPieces; NSString *text = example.text; expect([fullTextPieces isEqual:[NSArray arrayWithObject:text]]).to(be_truthy()); }); }); } copy]; describe(@"CDRExample", ^{ __block CDRExample *example; __block CDRReportDispatcher *dispatcher; NSString *exampleText = @"Example!"; __block BOOL beforeFocused; beforeEach(^{ dispatcher = nice_fake_for([CDRReportDispatcher class]); example = [[[CDRExample alloc] initWithText:exampleText andBlock:^{}] autorelease]; // if you focus any of these specs, they will fail without this beforeFocused = [CDRSpecHelper specHelper].shouldOnlyRunFocused; [CDRSpecHelper specHelper].shouldOnlyRunFocused = NO; // end }); afterEach(^{ [CDRSpecHelper specHelper].shouldOnlyRunFocused = beforeFocused; }); describe(@"runWithDispatcher:", ^{ __block CDRReportDispatcher *dispatcher; __block id weakCapturedObject; beforeEach(^{ dispatcher = nice_fake_for([CDRReportDispatcher class]); }); beforeEach(^{ NSString *capturedObject = [@"abc" mutableCopy]; objc_storeWeak(&weakCapturedObject, capturedObject); example = [[[CDRExample alloc] initWithText:exampleText andBlock:^{ // so we don't get a zero-value for runTime [NSThread sleepForTimeInterval:0.01]; [capturedObject length]; }] autorelease]; [capturedObject release]; capturedObject = nil; @autoreleasepool { objc_loadWeak(&weakCapturedObject) should_not be_nil; } // assert example is populated at the appropriate times dispatcher stub_method(@selector(runWillStartExample:)).and_do(^(NSInvocation *invocation) { example.state should equal(CDRExampleStateIncomplete); example.runTime should equal(0); example.startDate should_not be_nil; example.endDate should be_nil; }); dispatcher stub_method(@selector(runDidFinishExample:)).and_do(^(NSInvocation *invocation) { example.state should equal(CDRExampleStatePassed); example.runTime should_not equal(0); example.endDate should_not be_nil; }); [example runWithDispatcher:dispatcher]; }); it(@"should report the example", ^{ dispatcher should have_received(@selector(runWillStartExample:)).with(example); dispatcher should have_received(@selector(runDidFinishExample:)).with(example); }); it(@"should have its start date less than its end date", ^{ [example.endDate timeIntervalSinceDate:example.startDate] should be_greater_than(0); }); describe(@"running it a second time", ^{ it(@"should fail", ^{ ^{ [example runWithDispatcher:dispatcher]; } should raise_exception.with_reason([NSString stringWithFormat:@"Attempt to run example twice: %@", [example fullText]]); }); }); it(@"should allow captured objects to be deallocated once it has finished running", ^{ objc_loadWeak(&weakCapturedObject) should be_nil; }); }); describe(@"hasChildren", ^{ it(@"should return false", ^{ BOOL hasChildren = example.hasChildren; expect(hasChildren).to_not(be_truthy()); }); }); describe(@"isFocused", ^{ it(@"should return false by default", ^{ expect([example isFocused]).to_not(be_truthy()); }); it(@"should return false when example is not focused", ^{ example.focused = NO; expect([example isFocused]).to_not(be_truthy()); }); it(@"should return true when example is focused", ^{ example.focused = YES; expect([example isFocused]).to(be_truthy()); }); }); describe(@"hasFocusedExamples", ^{ it(@"should return false by default", ^{ expect([example hasFocusedExamples]).to_not(be_truthy()); }); it(@"should return false when example is not focused", ^{ example.focused = NO; expect([example hasFocusedExamples]).to_not(be_truthy()); }); it(@"should return true when example is focused", ^{ example.focused = YES; expect([example hasFocusedExamples]).to(be_truthy()); }); }); describe(@"state", ^{ context(@"for a newly created example", ^{ it(@"should be CDRExampleStateIncomplete", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateIncomplete)); }); }); context(@"for an example that has run and succeeded", ^{ beforeEach(^{ [example runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStatePassed", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStatePassed)); }); }); describe(@"for an example that has run and failed", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should fail" andBlock:^{ fail(@"fail"); }] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateFailed", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateFailed)); }); }); describe(@"for an example that has run and thrown an NSException", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should throw an NSException" andBlock:^{ [[NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil] raise]; }] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateError)); }); }); describe(@"for an example that has run and thrown something other than an NSException", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should throw some nonsense" andBlock:^{ @throw @"Some nonsense"; }] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStateError", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateError)); }); }); describe(@"for a pending example", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should be pending" andBlock:PENDING] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should be CDRExampleStatePending", ^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStatePending)); }); }); context(@"when running in the focused specs mode", ^{ context(@"for an example that was focused", ^{ beforeEach(^{ example.focused = YES; }); it(@"should be CDRExampleStatePassed", ^{ runInFocusedSpecsMode(example, dispatcher); expect([example state]).to(equal(CDRExampleStatePassed)); }); }); context(@"for an example that was not focused", ^{ beforeEach(^{ example.focused = NO; }); context(@"and its parent group was focused", ^{ beforeEach(^{ CDRExampleGroup *parentGroup = [[[CDRExampleGroup alloc] initWithText:@"Parent group"] autorelease]; parentGroup.focused = YES; example.parent = parentGroup; }); it(@"should be CDRExampleStatePassed", ^{ runInFocusedSpecsMode(example, dispatcher); expect([example state]).to(equal(CDRExampleStatePassed)); }); }); context(@"and its parent group was not focused", ^{ __block CDRExampleGroup *parentGroup; beforeEach(^{ parentGroup = [[[CDRExampleGroup alloc] initWithText:@"Parent group"] autorelease]; parentGroup.focused = NO; example.parent = parentGroup; }); it(@"should be CDRExampleStateSkipped", ^{ runInFocusedSpecsMode(example, dispatcher); expect([example state]).to(equal(CDRExampleStateSkipped)); }); context(@"and its parent's parent group was focused", ^{ beforeEach(^{ CDRExampleGroup *parentsParentGroup = [[[CDRExampleGroup alloc] initWithText:@"Parent's parent group"] autorelease]; parentsParentGroup.focused = YES; parentGroup.parent = parentsParentGroup; }); it(@"should be CDRExampleStatePassed", ^{ runInFocusedSpecsMode(example, dispatcher); expect([example state]).to(equal(CDRExampleStatePassed)); }); }); }); }); }); describe(@"KVO", ^{ __block id mockObserver; beforeEach(^{ mockObserver = [[[SimpleKeyValueObserver alloc] init] autorelease]; spy_on(mockObserver); }); it(@"should report when the state of a non-collection property changes", ^{ [example addObserver:mockObserver forKeyPath:@"state" options:0 context:NULL]; [example runWithDispatcher:dispatcher]; [example removeObserver:mockObserver forKeyPath:@"state"]; mockObserver should have_received("observeValueForKeyPath:ofObject:change:context:"); }); }); }); describe(@"progress", ^{ describe(@"when the state is incomplete", ^{ beforeEach(^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateIncomplete)); }); it(@"should return 0", ^{ float progress = example.progress; expect(progress).to(equal(0.0)); }); }); describe(@"when the state is passed", ^{ beforeEach(^{ [example runWithDispatcher:dispatcher]; CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStatePassed)); }); it(@"should return 1", ^{ float progress = example.progress; expect(progress).to(equal(1.0)); }); }); }); describe(@"fullText/fullTextInPieces", ^{ __block NSMutableDictionary *sharedExampleContext = [NSMutableDictionary dictionary]; beforeEach(^{ [sharedExampleContext setObject:example forKey:@"example"]; [sharedExampleContext setObject:exampleText forKey:@"exampleText"]; }); sharedExampleMethod(sharedExampleContext); }); describe(@"message", ^{ describe(@"for an incomplete example", ^{ beforeEach(^{ CDRExampleState state = example.state; expect(state).to(equal(CDRExampleStateIncomplete)); }); it(@"should return an empty string", ^{ NSString *message = example.message; expect(message).to(equal(@"")); }); }); describe(@"for a passing example", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should pass" andBlock:^{}] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should return an empty string", ^{ NSString *message = example.message; expect(message).to(equal(@"")); }); }); describe(@"for a pending example", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should pend" andBlock:nil] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should return an empty string", ^{ NSString *message = example.message; expect(message).to(equal(@"")); }); }); describe(@"for a skipped example", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should pend" andBlock:nil] autorelease]; example.focused = NO; runInFocusedSpecsMode(example, dispatcher); }); it(@"should return an empty string", ^{ NSString *message = example.message; expect(message).to(equal(@"")); }); }); describe(@"for a failing example", ^{ __block NSString *failureMessage = @"I should fail"; beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should fail" andBlock:^{[[CDRSpecFailure specFailureWithReason:failureMessage] raise];}] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should return the failure message", ^{ NSString *message = example.message; expect(message).to(equal(failureMessage)); }); }); describe(@"for an example that throws an NSException", ^{ __block NSException *exception; beforeEach(^{ exception = [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; example = [[[CDRExample alloc] initWithText:@"I should throw an exception" andBlock:^{ [exception raise]; }] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should return the description of the exception", ^{ expect(example.message).to(equal(exception.description)); }); }); describe(@"for an example that throws a non-NSException", ^{ __block NSString *failureMessage = @"wibble wobble"; beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should throw an exception" andBlock:^{ @throw failureMessage; }] autorelease]; [example runWithDispatcher:dispatcher]; }); it(@"should return the description of whatever was thrown", ^{ NSString *message = example.message; expect(message).to(equal(failureMessage)); }); }); }); describe(@"isPending", ^{ context(@"for an example with a block", ^{ it(@"should not report itself as pending", ^{ [example isPending] should be_falsy; }); context(@"after it has run", ^{ beforeEach(^{ [example runWithDispatcher:dispatcher]; }); it(@"should not report itself as pending", ^{ [example isPending] should be_falsy; }); }); }); context(@"for a pending example", ^{ beforeEach(^{ example = [[[CDRExample alloc] initWithText:@"I should be pending" andBlock:PENDING] autorelease]; }); it(@"should report itself as pending", ^{ [example isPending] should be_truthy; }); context(@"after it has run", ^{ beforeEach(^{ [example runWithDispatcher:dispatcher]; }); it(@"should report itself as pending", ^{ [example isPending] should be_truthy; }); }); }); }); describe(@"runTime", ^{ __block CDRExample *fastExample; __block CDRExample *slowExample; __block BOOL test; beforeEach(^{ test = NO; FibonacciCalculator *calculator = [[[FibonacciCalculator alloc] init] autorelease]; fastExample = [[[CDRExample alloc] initWithText:@"I'm Fast!" andBlock:^{ [calculator computeFibonnaciNumberVeryVeryQuickly:33]; }] autorelease]; slowExample = [[[CDRExample alloc] initWithText:@"I'm Slow!" andBlock:^{ [calculator computeFibonnaciNumberVeryVerySlowly:33]; }] autorelease]; }); it(@"should return the running time of the test", ^{ fastExample.runTime should equal(0); slowExample.runTime should equal(0); [fastExample runWithDispatcher:dispatcher]; [slowExample runWithDispatcher:dispatcher]; fastExample.runTime should be_greater_than(0); slowExample.runTime should be_greater_than(0); slowExample.runTime should be_greater_than(fastExample.runTime); }); }); describe(@"incorrectly configured examples", ^{ it(@"should raise when it() is called outside of a Cedar Spec", ^{ ^{ it(@"should raise when called outside a spec", ^{}); } should raise_exception.with_reason(@"it() was invoked outside of a spec. It may only be called when a spec has been defined with SPEC_BEGIN and SPEC_END macros."); }); it(@"should raise when describe() is called outside of a Cedar Spec", ^{ ^{ describe(@"should raise when called outside a spec", ^{}); } should raise_exception.with_reason(@"describe() was invoked outside of a spec. It may only be called when a spec has been defined with SPEC_BEGIN and SPEC_END macros."); }); it(@"should raise when context() is called outside of a Cedar Spec", ^{ ^{ context(@"should raise when called outside a spec", ^{}); } should raise_exception.with_reason(@"context() was invoked outside of a spec. It may only be called when a spec has been defined with SPEC_BEGIN and SPEC_END macros."); }); describe(@"when spec-validation is disabled", ^{ beforeEach(^{ CDRDisableSpecValidation(); }); afterEach(^{ CDREnableSpecValidation(); }); it(@"it() should should not raise", ^{ ^{ it(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); it(@"context() should not raise", ^{ ^{ context(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); it(@"describe() should not raise", ^{ ^{ describe(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); }); }); describe(@"during a test run", ^{ __block CedarTestSpecBuilder *specBuilder; beforeEach(^{ specBuilder = [[CedarTestSpecBuilder alloc] init]; }); afterEach(^{ // ensures run state is returned to a consistent state // if these lines are removed, then it's possible to put Cedar's internals // into a state where there is still a "current spec" to attach new examples to // ideally this behavior should be tested without the super class of CDRSpec // but that would require a refactor away from setting CDR_currentSpec directly // in our CDRSpec internals // nb: that would be a good refactor [specBuilder wrapWithDeclareBehaviors:^{}]; [specBuilder defineBehaviors]; }); it(@"should raise when it() is called", ^{ [specBuilder wrapWithDeclareBehaviors:^{ it(@"should raise when called outside a spec", ^{}); }]; ^{ [specBuilder defineBehaviors]; } should raise_exception .with_reason(@"it() was invoked during a test run. Make sure your 'it()' is not inside of an it() block."); }); it(@"should raise when context() is called", ^{ [specBuilder wrapWithDeclareBehaviors:^{ context(@"should raise when called outside a spec", ^{}); }]; ^{ [specBuilder defineBehaviors]; } should raise_exception .with_reason(@"context() was invoked during a test run. Make sure your 'context()' is not inside of an it() block."); }); it(@"should raise when describe() is called", ^{ [specBuilder wrapWithDeclareBehaviors:^{ describe(@"should raise when called outside a spec", ^{}); }]; ^{ [specBuilder defineBehaviors]; } should raise_exception .with_reason(@"describe() was invoked during a test run. Make sure your 'describe()' is not inside of an it() block."); }); describe(@"when spec-validation is disabled", ^{ beforeEach(^{ CDRDisableSpecValidation(); }); afterEach(^{ CDREnableSpecValidation(); }); it(@"it() should should not raise", ^{ ^{ it(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); it(@"context() should not raise", ^{ ^{ context(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); it(@"describe() should not raise", ^{ ^{ describe(@"should not raise when validation is disabled", ^{}); } should_not raise_exception; }); }); }); }); SPEC_END ================================================ FILE: Spec/CDRHooksSpec.mm ================================================ #import "Cedar.h" #import "CDRSpec.h" #import "CDRSpecRun.h" static BOOL conformantClassBeforeEachWasTriggered__ = NO; static BOOL conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = NO; static BOOL nonConformantClassBeforeEachWasTriggered__ = NO; static BOOL conformantClassAfterEachWasTriggered__ = NO; static BOOL conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = NO; static BOOL nonConformantClassAfterEachWasTriggered__ = NO; using namespace Cedar::Matchers; @interface ClassThatDoesntConformToCDRHooks : NSObject @end @interface ClassThatConformsToCDRHooks : NSObject @end @interface ClassThatConformsToCDRHooks () @end @implementation ClassThatConformsToCDRHooks + (void)beforeEach { conformantClassBeforeEachWasTriggered__ = YES; } + (void)afterEach { conformantClassAfterEachWasTriggered__ = YES; } @end @implementation ClassThatDoesntConformToCDRHooks + (void)beforeEach { nonConformantClassBeforeEachWasTriggered__ = YES; } + (void)afterEach { nonConformantClassAfterEachWasTriggered__ = YES; } @end @interface DummySpecForTestingHooks : CDRSpec @end @implementation DummySpecForTestingHooks - (void)declareBehaviors { self.fileName = [NSString stringWithUTF8String:__FILE__]; beforeEach(^{ conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = conformantClassBeforeEachWasTriggered__; }); it(@"just needs to have a spec", ^{ }); afterEach(^{ conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = conformantClassAfterEachWasTriggered__; }); } @end SPEC_BEGIN(CDRHooksSpec) //NB: If you focus any test here, you must also focus "just needs to run this spec" in DummySpecForTestingHooks describe(@"CDRHooks", ^{ beforeEach(^{ nonConformantClassBeforeEachWasTriggered__ = nonConformantClassAfterEachWasTriggered__ = conformantClassBeforeEachWasTriggered__ = conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__ = conformantClassAfterEachWasTriggered__ = conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__ = NO; CDRDisableSpecValidation(); CDRSpec *dummySpec = [[[DummySpecForTestingHooks class] alloc] init]; [dummySpec defineBehaviors]; id fakeStateTracker = nice_fake_for(@protocol(CDRStateTracking)); CDRSpecRun *specRun = [[CDRSpecRun alloc] initWithStateTracker:fakeStateTracker exampleReporters:@[]]; [specRun performSpecRun:^{ [dummySpec.rootGroup runWithDispatcher:specRun.dispatcher]; }]; CDREnableSpecValidation(); }); describe(@"+beforeEach", ^{ it(@"should not call +beforeEach on non-conformant classes", ^{ expect(nonConformantClassBeforeEachWasTriggered__).to(be_falsy); }); it(@"should run the +beforeEach BEFORE spec beforeEaches for CDRHooks conformers", ^{ expect(conformantClassBeforeEachWasTriggered__).to(be_truthy); expect(conformantClassBeforeEachWasTriggeredBeforeSpecBeforeEach__).to(be_truthy); }); }); describe(@"+afterEach", ^{ it(@"should not call +afterEach on non-conformant classes", ^{ expect(nonConformantClassAfterEachWasTriggered__).to(be_falsy); }); it(@"should run the +afterEach AFTER spec afterEaches for CDRHooks conformers", ^{ expect(conformantClassAfterEachWasTriggered__).to(be_truthy); expect(conformantClassAfterEachWasTriggeredBeforeSpecAfterEach__).to(be_falsy); }); }); }); SPEC_END ================================================ FILE: Spec/CDRNilSpec.mm ================================================ #import #import "CDRNil.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRNilSpec) describe(@"CDRNil", ^{ __block CDRNil *nilObject; beforeEach(^{ nilObject = [CDRNil nilObject]; }); it(@"should return itself when copied", ^{ CDRNil *copiedNil = [[nilObject copy] autorelease]; copiedNil should be_same_instance_as(nilObject); }); it(@"should be equal to other instances of CDRNil", ^{ CDRNil *anotherNil = [CDRNil nilObject]; anotherNil should equal(nilObject); }); it(@"should have a clear description indicating what it represents", ^{ [nilObject description] should equal(@""); }); }); SPEC_END ================================================ FILE: Spec/CDRSpecFailureSpec.mm ================================================ #import "Cedar.h" #import "CDRSymbolicator.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; static NSDictionary *reasonsToFileNames; SPEC_BEGIN(CDRSpecFailureSpec) reasonsToFileNames = [NSDictionary dictionaryWithObjectsAndKeys: @"File.h", @"File.h:123 reason", @"C:/Directory/File.h", @"C:/Directory/File.h:123 reason", @"Some Directory/File.m", @"Some Directory/File.m:123 reason", @"Some\\ Directory/File.m", @"Some\\ Directory/File.m:123 reason", @"Some Directory/File.m", @"Some Directory/File.m(123): reason", @"Some Directory (something)/File.m", @"Some Directory (something)/File.m(123) reason", nil]; describe(@"CDRSpecFailure", ^{ __block CDRSpecFailure *failure; context(@"for a failure instantiated only with a reason", ^{ context(@"when file name and line number are not specified inside reason", ^{ beforeEach(^{ failure = [CDRSpecFailure specFailureWithReason:@"reason"]; }); it(@"should return failure's reason", ^{ expect([failure reason]).to(equal(@"reason")); }); it(@"should return nil for file name", ^{ expect([failure fileName]).to(be_nil()); }); it(@"should return 0 for line number", ^{ expect([failure lineNumber]).to(equal(0)); }); }); context(@"when file name and line number are specified inside reason", ^{ for (NSString *reason in reasonsToFileNames) { NSString *fileName = [reasonsToFileNames objectForKey:reason]; it([NSString stringWithFormat:@"should return reason 'reason' parsed from '%@'", reason], ^{ CDRSpecFailure *failure = [CDRSpecFailure specFailureWithReason:reason]; expect([failure reason]).to(equal(@"reason")); }); it([NSString stringWithFormat:@"should return file name '%@' parsed from '%@'", fileName, reason], ^{ CDRSpecFailure *failure = [CDRSpecFailure specFailureWithReason:reason]; expect([failure fileName]).to(equal(fileName)); }); it([NSString stringWithFormat:@"should return line number '123' parsed from '%@'", reason], ^{ CDRSpecFailure *failure = [CDRSpecFailure specFailureWithReason:reason]; expect([failure lineNumber]).to(equal(123)); }); } }); }); context(@"for a failure instantiated with reason, file name and line number", ^{ beforeEach(^{ failure = [CDRSpecFailure specFailureWithReason:@"reason" fileName:@"File.m" lineNumber:123]; }); it(@"should return failure's reason", ^{ expect([failure reason]).to(equal(@"reason")); }); it(@"should return failure's file name", ^{ expect([failure fileName]).to(equal(@"File.m")); }); it(@"should return failure's line number", ^{ expect([failure lineNumber]).to(equal(123)); }); }); context(@"for a failure instantiated with a raised object", ^{ context(@"when raised object is a subclass of NSException", ^{ context(@"when file name and line number are specified in exception's userInfo", ^{ beforeEach(^{ NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"File.m", @"fileName", [NSNumber numberWithInt:123], @"lineNumber", nil]; NSException *exception = [NSException exceptionWithName:@"boo" reason:@"exception reason" userInfo:userInfo]; failure = [CDRSpecFailure specFailureWithRaisedObject:exception]; }); it(@"should return exception's reason", ^{ expect([failure reason]).to(equal(@"exception reason")); }); it(@"should return file name specified in exception's userInfo", ^{ expect([failure fileName]).to(equal(@"File.m")); }); it(@"should return line number specified in exception's userInfo", ^{ expect([failure lineNumber]).to(equal(123)); }); }); context(@"when file name and line number are not specified in userInfo of exception", ^{ beforeEach(^{ NSException *exception = [NSException exceptionWithName:@"boo" reason:@"exception reason" userInfo:nil]; failure = [CDRSpecFailure specFailureWithRaisedObject:exception]; }); it(@"should return raised object's reason", ^{ expect([failure reason]).to(equal(@"exception reason")); }); it(@"should return nil for file name", ^{ expect([failure fileName]).to(be_nil()); }); it(@"should return 0 for line number", ^{ expect([failure lineNumber]).to(equal(0)); }); }); }); context(@"when raised object is not a subclass of NSException", ^{ beforeEach(^{ failure = [CDRSpecFailure specFailureWithRaisedObject:[NSNumber numberWithInt:19901113]]; }); it(@"should return raised object's description for reason", ^{ expect([failure reason]).to(equal(@"19901113")); }); it(@"should return nil for file name", ^{ expect([failure fileName]).to(be_nil()); }); it(@"should return 0 for line number", ^{ expect([failure lineNumber]).to(equal(0)); }); }); }); describe(@"-callStackSymbolicatedSymbols", ^{ __block NSString *symbols; __block NSError *error; __block id raisedObject; subjectAction(^{ CDRSpecFailure *failure = [CDRSpecFailure specFailureWithRaisedObject:raisedObject]; error = nil; symbols = [failure callStackSymbolicatedSymbols:&error]; }); context(@"when raised object provides call stack return addresses", ^{ void (^objectRaiser)(void) = ^{ [[NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil] raise]; }; beforeEach(^{ // Raise and then catch actual exception // to populate its callStackReturnAddresses. @try { objectRaiser(); } @catch (NSException *e) { raisedObject = e; } }); #if !CDR_SYMBOLICATION_AVAILABLE context(@"when symbolication is not available (devices)", ^{ it(@"returns nil", ^{ symbols should be_nil; }); it(@"sets not available error", ^{ error.domain should equal(kCDRSymbolicatorErrorDomain); error.code should equal(kCDRSymbolicatorErrorNotAvailable); [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey] \ should be_instance_of([NSString class]).or_any_subclass(); }); }); #else context(@"when symbolication is available (mac, simulator)", ^{ context(@"when symbolication is successful", ^{ it(@"returns string with symbolicated call stack " "showing originating error location closest to the top", ^{ symbols should contain( @" *CDRSpecFailureSpec.mm:156\n" " *CDRSpecFailureSpec.mm:162\n" ); }); it(@"indicates unsymbolicated portions of call stack with '...'", ^{ symbols should contain( @"Call stack:\n" " ...\n" // <-+ objc_exception_throw, " *CDRSpecFailureSpec.mm" // | [NSException raise:...], etc. ); }); it(@"includes asterisk before every path " "because paths are not absolute and " "Xcode plugins need to be able to recognize them", ^{ symbols should contain(@"*CDRSpecFailureSpec.mm"); }); it(@"does not set error", ^{ error should be_nil; }); }); context(@"when symbolication is not successful", ^{ beforeEach(^{ NSNumber *badAddress = [NSNumber numberWithUnsignedInteger:123]; NSArray *addresses = [NSArray arrayWithObject:badAddress]; spy_on(raisedObject); raisedObject stub_method("callStackReturnAddresses").and_return(addresses); }); it(@"returns nil", ^{ symbols should be_nil; }); it(@"sets not successful error", ^{ error.domain should equal(kCDRSymbolicatorErrorDomain); error.code should equal(kCDRSymbolicatorErrorNotSuccessful); [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey] \ should be_instance_of([NSString class]).or_any_subclass(); }); }); }); #endif }); context(@"when raised object does not provide call stack return addresses", ^{ beforeEach(^{ raisedObject = @"failure"; }); it(@"returns nil", ^{ symbols should be_nil; }); }); }); }); SPEC_END ================================================ FILE: Spec/CDRSpecRunSpec.mm ================================================ #import #import "CDRSpecRun.h" #import "CDRStateTracking.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRSpecRunSpec) describe(@"CDRSpecRun", ^{ __block CDRSpecRun *subject; __block id stateTracker; beforeEach(^{ CDRDisableSpecValidation(); }); afterEach(^{ CDREnableSpecValidation(); }); beforeEach(^{ stateTracker = fake_for(@protocol(CDRStateTracking)); stateTracker stub_method(@selector(didStartPreparingTests)); subject = [[CDRSpecRun alloc] initWithStateTracker:stateTracker exampleReporters:@[]]; }); it(@"should move the state into CedarRunStatePreparingTests", ^{ stateTracker should have_received(@selector(didStartPreparingTests)); }); it(@"should change the state to running tests and then be finished", ^{ stateTracker stub_method(@selector(didStartRunningTests)); [subject performSpecRun:^{ stateTracker should have_received(@selector(didStartRunningTests)); stateTracker stub_method(@selector(didFinishRunningTests)); }]; stateTracker should have_received(@selector(didFinishRunningTests)); }); }); SPEC_END ================================================ FILE: Spec/CDRSpecSpec.mm ================================================ #import "Cedar.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRSpecSpec) describe(@"CDRSpec", ^{ __block CDRSpec *spec; beforeEach(^{ spec = [[[CDRSpec alloc] init] autorelease]; spy_on(spec.symbolicator); spec.symbolicator stub_method("symbolicateAddresses:error:").and_return(YES); spec.symbolicator stub_method("lineNumberForStackAddress:").and_do(^(NSInvocation *i){ NSUInteger lineNumber; [i getArgument:&lineNumber atIndex:2]; [i setReturnValue:&lineNumber]; }); }); CDRExampleGroup *(^exampleGroup)(int) = ^(int lineNumber){ CDRExampleGroup *group = [[[CDRExampleGroup alloc] initWithText:@"Group"] autorelease]; group.stackAddress = lineNumber; return group; }; describe(@"-markAsFocusedClosestToLineNumber:", ^{ context(@"with a single group", ^{ it(@"marks group as focused if line number is above the group", ^{ spec.rootGroup = exampleGroup(1); [spec markAsFocusedClosestToLineNumber:0]; spec.rootGroup.isFocused should be_truthy; }); it(@"marks group as focused if line number is exactly on the first line of the group", ^{ spec.rootGroup = exampleGroup(1); [spec markAsFocusedClosestToLineNumber:1]; spec.rootGroup.isFocused should be_truthy; }); it(@"marks group as focused if line number is below the first line of the group", ^{ spec.rootGroup = exampleGroup(1); [spec markAsFocusedClosestToLineNumber:2]; spec.rootGroup.isFocused should be_truthy; }); }); context(@"with a group that contains another group", ^{ it(@"marks outer group as focused if line number is below the first line of outer group and above the first line of inner group", ^{ spec.rootGroup = exampleGroup(1); CDRExampleGroup *innerGroup = exampleGroup(3); [spec.rootGroup add:innerGroup]; [spec markAsFocusedClosestToLineNumber:2]; spec.rootGroup.isFocused should be_truthy; innerGroup.isFocused should_not be_truthy; }); it(@"marks inner group as focused if line number is below the first line of outer group and exactly on the first line of inner group", ^{ spec.rootGroup = exampleGroup(1); CDRExampleGroup *innerGroup = exampleGroup(3); [spec.rootGroup add:innerGroup]; [spec markAsFocusedClosestToLineNumber:3]; spec.rootGroup.isFocused should_not be_truthy; innerGroup.isFocused should be_truthy; }); it(@"marks inner group as focused if line number is below both first lines of outer and inner groups", ^{ spec.rootGroup = exampleGroup(1); CDRExampleGroup *innerGroup = exampleGroup(3); [spec.rootGroup add:innerGroup]; [spec markAsFocusedClosestToLineNumber:5]; spec.rootGroup.isFocused should_not be_truthy; innerGroup.isFocused should be_truthy; }); }); }); }); SPEC_END ================================================ FILE: Spec/CDRSymbolicatorSpec.mm ================================================ #import "Cedar.h" #import "CDRSymbolicator.h" using namespace Cedar::Matchers; SPEC_BEGIN(CDRSymbolicatorSpec) describe(@"CDRSymbolicator", ^{ __block CDRSymbolicator *symbolicator; beforeEach(^{ symbolicator = [[[CDRSymbolicator alloc] init] autorelease]; }); #if !CDR_SYMBOLICATION_AVAILABLE context(@"when symbolication is not available (devices and watchOS)", ^{ __block NSArray *addresses; __block NSError *error; beforeEach(^{ NSNumber *address = [NSNumber numberWithUnsignedInteger:123]; addresses = [NSArray arrayWithObject:address]; }); subjectAction(^{ error = nil; [symbolicator symbolicateAddresses:addresses error:&error]; }); it(@"does not return filename or line number", ^{ [symbolicator fileNameForStackAddress:0] should be_nil; [symbolicator lineNumberForStackAddress:0] should equal(0); }); it(@"sets not available error", ^{ error.domain should equal(kCDRSymbolicatorErrorDomain); error.code should equal(kCDRSymbolicatorErrorNotAvailable); [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey] \ should be_instance_of([NSString class]).or_any_subclass(); }); }); #else context(@"when symbolication is available (osx, simulator)", ^{ context(@"when symbolication is successful", ^{ __block CDRExample *example; __block CDRExampleGroup *group; beforeEach(^{ // disabled so we can call it() directly CDRDisableSpecValidation(); }); afterEach(^{ CDREnableSpecValidation(); }); void (^verifyFileNameAndLineNumber)(CDRExampleBase *, NSString *, int) = ^(CDRExampleBase *b, NSString *fileName, int lineNumber) { NSNumber *address = [NSNumber numberWithUnsignedInteger:b.stackAddress]; NSArray *addresses = [NSArray arrayWithObject:address]; NSError *error = nil; [symbolicator symbolicateAddresses:addresses error:&error] should be_truthy; error should be_nil; [[symbolicator fileNameForStackAddress:b.stackAddress] hasSuffix:fileName] should be_truthy; [symbolicator lineNumberForStackAddress:b.stackAddress] should equal(lineNumber); }; it(@"identifies file name and line number of an it", ^{ example = it(@"it", ^{}); verifyFileNameAndLineNumber(example, @"CDRSymbolicatorSpec.mm", __LINE__-1); }); it(@"identifies file name line number of a describe", ^{ group = describe(@"describe", ^{}); verifyFileNameAndLineNumber(group, @"CDRSymbolicatorSpec.mm", __LINE__-1); }); it(@"identifies file name line number of a context", ^{ group = context(@"context", ^{}); verifyFileNameAndLineNumber(group, @"CDRSymbolicatorSpec.mm", __LINE__-1); }); it(@"identifies file name line number of a nested it", ^{ describe(@"describe", ^{ example = it(@"it", ^{}); }); verifyFileNameAndLineNumber(example, @"CDRSymbolicatorSpec.mm", __LINE__-2); }); it(@"identifies file name line number of a nested describe", ^{ describe(@"describe", ^{ group = describe(@"describe", ^{}); }); verifyFileNameAndLineNumber(group, @"CDRSymbolicatorSpec.mm", __LINE__-2); }); it(@"identifies file name line number of a nested context", ^{ describe(@"describe", ^{ group = context(@"context", ^{}); }); verifyFileNameAndLineNumber(group, @"CDRSymbolicatorSpec.mm", __LINE__-2); }); }); context(@"when symbolication is not successful", ^{ __block NSArray *addresses; __block NSError *error; beforeEach(^{ NSNumber *badAddress = [NSNumber numberWithUnsignedInteger:123]; addresses = [NSArray arrayWithObject:badAddress]; }); subjectAction(^{ error = nil; [symbolicator symbolicateAddresses:addresses error:&error] should be_falsy; }); it(@"does not return filename or line number", ^{ [symbolicator fileNameForStackAddress:0] should be_nil; [symbolicator lineNumberForStackAddress:0] should equal(0); }); it(@"sets not successful error", ^{ error.domain should equal(kCDRSymbolicatorErrorDomain); error.code should equal(kCDRSymbolicatorErrorNotSuccessful); [error.userInfo objectForKey:kCDRSymbolicatorErrorMessageKey] \ should be_instance_of([NSString class]).or_any_subclass(); }); }); }); #endif }); SPEC_END ================================================ FILE: Spec/CDRTypeUtilitiesSpec.mm ================================================ #import "Cedar.h" #import "CDRTypeUtilities.h" #import "CDRNil.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRTypeUtilitiesSpec) describe(@"CDRTypeUtilities", ^{ describe(@"mapping type encodings and bytes to objective-c objects", ^{ it(@"should return a boxed number for char", ^{ char c = 'c'; [CDRTypeUtilities boxedObjectOfBytes:&c ofObjCType:@encode(char)] should equal(@(c)); }); it(@"should return a boxed number for int", ^{ int i = 23456; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(int)] should equal(@(i)); }); it(@"should return a boxed number for short", ^{ short i = 4456; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(short)] should equal(@(i)); }); it(@"should return a boxed number for long", ^{ long i = 5345; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(long)] should equal(@(i)); }); it(@"should return a boxed number for a long long", ^{ long long i = 63453; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(long long)] should equal(@(i)); }); it(@"should return a boxed number for unsigned char", ^{ unsigned char c = 'c'; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&c ofObjCType:@encode(unsigned char)] should equal(@(c)); }); it(@"should return a boxed number for unsigned int", ^{ unsigned int i = 21234; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(unsigned int)] should equal(@(i)); }); it(@"should return a boxed number for unsigned short", ^{ unsigned short i = 4456; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(unsigned short)] should equal(@(i)); }); it(@"should return a boxed number for unsigned long", ^{ unsigned long long i = 6346; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(long long)] should equal(@(i)); }); it(@"should return a boxed number for unsigned long long", ^{ unsigned long long i = 7234; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(unsigned long long)] should equal(@(i)); }); it(@"should return a boxed number for float", ^{ float i = 1.5f; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(float)] should equal(@(i)); }); it(@"should return a boxed number for double", ^{ double i = 1.5; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&i ofObjCType:@encode(double)] should equal(@(i)); }); it(@"should return a boxed number for a non-objc bool", ^{ bool b = true; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&b ofObjCType:@encode(bool)] should equal(@YES); }); it(@"should return a NSString for a c string", ^{ const char *text = "Hello world!"; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&text ofObjCType:@encode(const char *)] should equal(@"Hello world!"); }); it(@"should return a NSString for a non-null but empty c string", ^{ const char *text = ""; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&text ofObjCType:@encode(const char *)] should equal(@""); }); it(@"should return the objective-c object it was given", ^{ id foo = @"bar"; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foo ofObjCType:@encode(id)] should be_same_instance_as(foo); }); describe(@"given a nil value", ^{ context(@"typed as an object", ^{ it(@"should return CDRNil", ^{ id nilParam = nil; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&nilParam ofObjCType:@encode(id)] should equal([CDRNil nilObject]); }); }); context(@"typed as Class", ^{ it(@"should return CDRNil", ^{ Class nilParam = nil; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&nilParam ofObjCType:@encode(Class)] should equal([CDRNil nilObject]); }); }); context(@"typed as as block", ^{ it(@"should return CDRNil", ^{ void (^nilBlock)(NSString *) = nil; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&nilBlock ofObjCType:@encode(void (^)(NSString *))] should equal([CDRNil nilObject]); }); }); context(@"typed as a char *", ^{ it(@"should return CDRNil", ^{ char *nilCharPointer = NULL; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&nilCharPointer ofObjCType:@encode(char *)] should equal([CDRNil nilObject]); }); }); context(@"typed as a const char *", ^{ it(@"should return CDRNil", ^{ const char *foobar = NULL; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foobar ofObjCType:@encode(const char *)] should equal([CDRNil nilObject]); }); }); context(@"typed as a SEL", ^{ it(@"should return CDRNil", ^{ SEL mySelector = nil; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&mySelector ofObjCType:@encode(SEL)] should equal([CDRNil nilObject]); }); }); }); it(@"should return the class it was given", ^{ Class aClass = [NSObject class]; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&aClass ofObjCType:@encode(Class)] should equal(aClass); }); it(@"should return a string for a selector", ^{ SEL selector = @selector(description); [CDRTypeUtilities boxedObjectOfBytes:(const void *)&selector ofObjCType:@encode(SEL)] should equal(NSStringFromSelector(selector)); }); it(@"should return the objective-c block it was given", ^{ void (^aBlock)() = ^{}; (id)[CDRTypeUtilities boxedObjectOfBytes:(const void *)&aBlock ofObjCType:@encode(void(^)())] should equal((id)aBlock); }); describe(@"given a char *", ^{ it(@"should return an NSString when given a non-empty char *", ^{ char *foobar = (char *)"hello world"; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foobar ofObjCType:@encode(char *)] should equal(@"hello world"); }); it(@"should return an empty NSString when given an empty char *", ^{ char *foobar = (char *)""; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foobar ofObjCType:@encode(char *)] should equal(@""); }); }); describe(@"given a const char *", ^{ it(@"should return a string for a non-empty const char *", ^{ const char *foobar = "hello world"; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foobar ofObjCType:@encode(const char *)] should equal(@"hello world"); }); it(@"should return an empty string for an empty const char *", ^{ const char *foobar = ""; [CDRTypeUtilities boxedObjectOfBytes:(const void *)&foobar ofObjCType:@encode(const char *)] should equal(@""); }); }); it(@"should return an NSValue for other Types", ^{ CGRect r = CGRectMake(1, 2, 3, 4); (id)[CDRTypeUtilities boxedObjectOfBytes:(const void *)&r ofObjCType:@encode(CGRect)] should equal([NSValue valueWithBytes:&r objCType:@encode(CGRect)]); }); }); describe(@"mapping type encodings to type names", ^{ it(@"should return the type name for 'c'", ^{ [CDRTypeUtilities typeNameForEncoding:"c"] should equal(@"char"); }); it(@"should return the type name for 'i'", ^{ [CDRTypeUtilities typeNameForEncoding:"i"] should equal(@"int"); }); it(@"should return the type name for 's'", ^{ [CDRTypeUtilities typeNameForEncoding:"s"] should equal(@"short"); }); it(@"should return the type name for 'l'", ^{ [CDRTypeUtilities typeNameForEncoding:"l"] should equal(@"long"); }); it(@"should return the type name for 'q'", ^{ BOOL longMatchesLongLong = (sizeof(long)==sizeof(long long)); NSString *typeName = longMatchesLongLong ? @"long" : @"long long"; [CDRTypeUtilities typeNameForEncoding:"q"] should equal(typeName); }); it(@"should return the type name for 'C'", ^{ [CDRTypeUtilities typeNameForEncoding:"C"] should equal(@"unsigned char"); }); it(@"should return the type name for 'I'", ^{ [CDRTypeUtilities typeNameForEncoding:"I"] should equal(@"unsigned int"); }); it(@"should return the type name for 'S'", ^{ [CDRTypeUtilities typeNameForEncoding:"S"] should equal(@"unsigned short"); }); it(@"should return the type name for 'L'", ^{ [CDRTypeUtilities typeNameForEncoding:"L"] should equal(@"unsigned long"); }); it(@"should return the type name for 'Q'", ^{ BOOL longMatchesLongLong = (sizeof(long)==sizeof(long long)); NSString *typeName = longMatchesLongLong ? @"unsigned long" : @"unsigned long long"; [CDRTypeUtilities typeNameForEncoding:"Q"] should equal(typeName); }); it(@"should return the type name for 'f'", ^{ [CDRTypeUtilities typeNameForEncoding:"f"] should equal(@"float"); }); it(@"should return the type name for 'd'", ^{ [CDRTypeUtilities typeNameForEncoding:"d"] should equal(@"double"); }); it(@"should return the type name for 'B'", ^{ [CDRTypeUtilities typeNameForEncoding:"B"] should equal(@"bool"); }); it(@"should return the type name for 'v'", ^{ [CDRTypeUtilities typeNameForEncoding:"v"] should equal(@"void"); }); it(@"should return the type name for '*'", ^{ [CDRTypeUtilities typeNameForEncoding:"*"] should equal(@"char *"); }); it(@"should return the type name for '@'", ^{ [CDRTypeUtilities typeNameForEncoding:"@"] should equal(@"id"); }); it(@"should return the type name for '#'", ^{ [CDRTypeUtilities typeNameForEncoding:"#"] should equal(@"Class"); }); it(@"should return the type name for ':'", ^{ [CDRTypeUtilities typeNameForEncoding:":"] should equal(@"SEL"); }); it(@"should return the type name for '@?'", ^{ [CDRTypeUtilities typeNameForEncoding:"@?"] should equal(@""); }); it(@"should return the type name for '?'", ^{ [CDRTypeUtilities typeNameForEncoding:"?"] should equal(@""); }); context(@"for structs", ^{ /* struct a_tagged_struct { int a; }; typedef struct { int a; } an_untagged_struct; */ it(@"should return the type name for '{a_tagged_struct=i}'", ^{ [CDRTypeUtilities typeNameForEncoding:"{a_tagged_struct=i}"] should equal(@"struct a_tagged_struct"); }); it(@"should return the type name for '{?=i}'", ^{ [CDRTypeUtilities typeNameForEncoding:"{?=i}"] should equal(@"untagged struct"); }); }); context(@"for unions", ^{ /* union a_tagged_union { int a; }; typedef union { int a; } an_untagged_union; */ it(@"should return the type name for '(a_tagged_union=i)'", ^{ [CDRTypeUtilities typeNameForEncoding:"(a_tagged_union=i)"] should equal(@"union a_tagged_union"); }); it(@"should return the type name for '(?=i)'", ^{ [CDRTypeUtilities typeNameForEncoding:"(?=i)"] should equal(@"untagged union"); }); }); context(@"for arrays", ^{ it(@"should return the type name for '[2i]'", ^{ [CDRTypeUtilities typeNameForEncoding:"[2i]"] should equal(@"int[2]"); }); it(@"should return the type name for '[2@?]'", ^{ [CDRTypeUtilities typeNameForEncoding:"[2@?]"] should equal(@"[2]"); }); it(@"should return the type name for '[2{a_tagged_struct=i}]'", ^{ [CDRTypeUtilities typeNameForEncoding:"[2{a_tagged_struct=i}]"] should equal(@"struct a_tagged_struct[2]"); }); }); context(@"for pointers", ^{ it(@"should return the type name for '^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"^i"] should equal(@"int *"); }); it(@"should return the type name for '^@'", ^{ [CDRTypeUtilities typeNameForEncoding:"^@"] should equal(@"id *"); }); it(@"should return the type name for '^^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"^^i"] should equal(@"int **"); }); it(@"should return the type name for '^{a_tagged_struct=i}'", ^{ [CDRTypeUtilities typeNameForEncoding:"^{a_tagged_struct=i}"] should equal(@"struct a_tagged_struct *"); }); it(@"should return the type name for '^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"^i"] should equal(@"int *"); }); it(@"should return the type name for '^*'", ^{ [CDRTypeUtilities typeNameForEncoding:"^*"] should equal(@"char **"); }); }); context(@"with modifiers", ^{ it(@"should return the type name for 'r^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"r^i"] should equal(@"const int *"); }); it(@"should return the type name for 'n^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"n^i"] should equal(@"in int *"); }); it(@"should return the type name for 'N^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"N^i"] should equal(@"inout int *"); }); it(@"should return the type name for 'o^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"o^i"] should equal(@"out int *"); }); it(@"should return the type name for 'O^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"O^i"] should equal(@"bycopy int *"); }); it(@"should return the type name for 'R^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"R^i"] should equal(@"byref int *"); }); it(@"should return the type name for 'V^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"V^i"] should equal(@"oneway int *"); }); it(@"should return the type name for 'RVr^i'", ^{ [CDRTypeUtilities typeNameForEncoding:"RVr^i"] should equal(@"byref oneway const int *"); }); }); }); }); SPEC_END ================================================ FILE: Spec/Doubles/CDRClassFakeSpec.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" #import "ObjectWithForwardingTarget.h" #import "ObjectWithWeakDelegate.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRClassFakeSpec) sharedExamplesFor(@"a Cedar class fake", ^(NSDictionary *sharedContext) { __block SimpleIncrementer *fake; SEL wibble_wobbleSelector = NSSelectorFromString(@"wibble_wobble"); beforeEach(^{ fake = [sharedContext objectForKey:@"double"]; }); describe(@"-respondsToSelector:", ^{ context(@"when an instance method is defined", ^{ it(@"should return true", ^{ [fake respondsToSelector:@selector(value)] should be_truthy; }); }); context(@"when an instance method is not defined", ^{ it(@"should return false", ^{ [fake respondsToSelector:wibble_wobbleSelector] should_not be_truthy; }); }); }); describe(@"-description", ^{ it(@"should return the description of the faked class", ^{ fake.description should contain(@"Fake implementation of SimpleIncrementer class"); }); }); describe(@"-conformsToProtocol:", ^{ it(@"should be true for protocols adopted by the faked class", ^{ [fake conformsToProtocol:@protocol(SimpleIncrementer)] should be_truthy; }); it(@"should be true for protocols inherited by protocols adopted by the faked class", ^{ [fake conformsToProtocol:@protocol(InheritedProtocol)] should be_truthy; }); it(@"should not be true for other protocols", ^{ [fake conformsToProtocol:@protocol(CedarDouble)] should_not be_truthy; [fake conformsToProtocol:@protocol(NSCoding)] should_not be_truthy; }); }); describe(@"-isKindOfClass:", ^{ it(@"should be true for the faked class", ^{ [fake isKindOfClass:[SimpleIncrementer class]] should be_truthy; }); it(@"should be true for superclasses of the faked class", ^{ [fake isKindOfClass:[IncrementerBase class]] should be_truthy; }); it(@"should be false for other classes", ^{ [fake isKindOfClass:[CDRClassFake class]] should_not be_truthy; [fake isKindOfClass:[NSString class]] should_not be_truthy; }); }); it(@"-class should return the faked class", ^{ [fake class] should equal([SimpleIncrementer class]); }); }); describe(@"CDRClassFake", ^{ describe(@"fake_for(Class)", ^{ __block SimpleIncrementer *fake; beforeEach(^{ fake = fake_for([SimpleIncrementer class]); [[CDRSpecHelper specHelper].sharedExampleContext setObject:fake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar class fake"); itShouldBehaveLike(@"a Cedar ordinary fake"); context(@"when calling a method which has not been stubbed", ^{ it(@"should raise an exception", ^{ ^{ [fake value]; } should raise_exception; }); }); }); describe(@"nice_fake_for(Class)", ^{ __block SimpleIncrementer *niceFake; beforeEach(^{ niceFake = nice_fake_for([SimpleIncrementer class]); [[CDRSpecHelper specHelper].sharedExampleContext setObject:niceFake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar class fake"); itShouldBehaveLike(@"a Cedar nice fake"); context(@"when calling a method which has not been stubbed", ^{ it(@"should allow method invocation without stubbing", ^{ [niceFake incrementBy:3]; }); it(@"should default to returning a 0", ^{ expect([niceFake aVeryLargeNumber]).to(equal(0)); }); }); }); describe(@"faking a class with interface categories", ^{ __block ObjectWithForwardingTarget *fake; beforeEach(^{ fake = fake_for([ObjectWithForwardingTarget class]); }); it(@"should allow stubbing of methods declared in a category without a corresponding category implementation", ^{ fake stub_method("count").and_return((NSUInteger)42); fake.count should equal(42); }); it(@"should raise a descriptive exception when a method signature couldn't be resolved", ^{ ^{ fake stub_method("unforwardedUnimplementedMethod"); } should raise_exception.with_reason([NSString stringWithFormat:@"Attempting to stub method , which double <%@> does not respond to", [fake description]]); }); }); describe(@"using Key Value Coding", ^{ __block ObjectWithWeakDelegate *fake; __block id delegate; describe(@"to set values", ^{ beforeEach(^{ delegate = nice_fake_for(@protocol(ExampleDelegate)); }); describe(@"a nice fake", ^{ beforeEach(^{ fake = nice_fake_for([ObjectWithWeakDelegate class]); }); sharedExamplesFor(@"silently handling KVC setters", ^(NSDictionary *sharedContext) { it(@"should not blow up, silently failing when setValue:forKey: is invoked", ^{ [fake setValue:nice_fake_for(@protocol(ExampleDelegate)) forKey:sharedContext[@"key"]]; fake.delegate should be_nil; }); it(@"should not blow up, silently failing when setValue:forKeyPath: is invoked", ^{ [fake setValue:nice_fake_for(@protocol(ExampleDelegate)) forKeyPath:sharedContext[@"key"]]; fake.delegate should be_nil; }); it(@"should record that it has received setValue:forKey:", ^{ [fake setValue:delegate forKey:sharedContext[@"key"]]; fake should have_received(@selector(setValue:forKey:)).with(delegate, sharedContext[@"key"]); }); it(@"should record that it has received setValue:forKeyPath:", ^{ [fake setValue:delegate forKeyPath:sharedContext[@"key"]]; fake should have_received(@selector(setValue:forKeyPath:)).with(delegate, sharedContext[@"key"]); }); }); describe(@"with a key that is KVC-compliant", ^{ itShouldBehaveLike(@"silently handling KVC setters", ^(NSMutableDictionary *context) { context[@"key"] = @"delegate"; }); }); describe(@"with a key that is not KVC-compliant", ^{ itShouldBehaveLike(@"silently handling KVC setters", ^(NSMutableDictionary *context) { context[@"key"] = @"bogus"; }); }); }); describe(@"a strict fake", ^{ beforeEach(^{ fake = fake_for([ObjectWithWeakDelegate class]); }); context(@"when not stubbed first", ^{ it(@"should blow up when setValue:forKey: is invoked", ^{ ^{ [fake setValue:delegate forKey:@"delegate"]; } should raise_exception.with_name(NSInternalInconsistencyException).with_reason([NSString stringWithFormat:@"Attempting to set value <%@> for key <%@>, which must be stubbed first", delegate, @"delegate"]); }); }); context(@"when stubbed", ^{ it(@"should happily receive -setValue:forKey:", ^{ fake stub_method(@selector(setValue:forKey:)); [fake setValue:delegate forKey:@"delegate"]; fake should have_received(@selector(setValue:forKey:)).with(delegate).and_with(@"delegate"); }); it(@"should happily receive -setValue:forKeyPath:", ^{ fake stub_method(@selector(setValue:forKeyPath:)); [fake setValue:delegate forKeyPath:@"delegate"]; fake should have_received(@selector(setValue:forKeyPath:)).with(delegate).and_with(@"delegate"); }); }); }); }); describe(@"to get values", ^{ describe(@"a nice fake", ^{ beforeEach(^{ fake = nice_fake_for([ObjectWithWeakDelegate class]); }); sharedExamplesFor(@"silently handling KVC getters", ^(NSDictionary *sharedContext) { it(@"should not blow up, returning nil when valueForKey: is invoked", ^{ [fake valueForKey:sharedContext[@"key"]] should be_nil; }); it(@"should not blow up, returning nil when valueForKeyPath: is invoked", ^{ [fake valueForKeyPath:sharedContext[@"key"]] should be_nil; }); it(@"should record that it has received valueForKey:", ^{ [fake valueForKey:sharedContext[@"key"]]; fake should have_received(@selector(valueForKey:)).with(sharedContext[@"key"]); }); it(@"should record that it has received valueForKeyPath:", ^{ [fake valueForKeyPath:sharedContext[@"key"]]; fake should have_received(@selector(valueForKeyPath:)).with(sharedContext[@"key"]); }); }); describe(@"with a key that is KVC-compliant", ^{ itShouldBehaveLike(@"silently handling KVC getters", ^(NSMutableDictionary *context) { context[@"key"] = @"delegate"; }); }); describe(@"with a key that is not KVC-compliant", ^{ itShouldBehaveLike(@"silently handling KVC getters", ^(NSMutableDictionary *context) { context[@"key"] = @"bogus"; }); }); }); describe(@"a strict fake", ^{ beforeEach(^{ fake = fake_for([ObjectWithWeakDelegate class]); }); context(@"when not stubbed first", ^{ it(@"should blow up when valueForKey: is invoked", ^{ ^{ [fake valueForKey:@"delegate"]; } should raise_exception.with_name(NSInternalInconsistencyException).with_reason([NSString stringWithFormat:@"Attempting to get value for key <%@>, which must be stubbed first", @"delegate"]); }); }); context(@"when stubbed with no return value", ^{ it(@"should happily receive -valueForKey: and return nil", ^{ fake stub_method(@selector(valueForKey:)); [fake valueForKey:@"delegate"]; fake should have_received(@selector(valueForKey:)).with(@"delegate"); }); it(@"should happily receive -valueForKeyPath:", ^{ fake stub_method(@selector(valueForKeyPath:)); [fake valueForKeyPath:@"delegate"]; fake should have_received(@selector(valueForKeyPath:)).with(@"delegate"); }); }); context(@"when stubbed with a return value", ^{ beforeEach(^{ delegate = nice_fake_for(@protocol(ExampleDelegate)); }); it(@"should receive -valueForKey: and return the stubbed value", ^{ fake stub_method(@selector(valueForKey:)).with(@"delegate").and_return(delegate); [fake valueForKey:@"delegate"] should be_same_instance_as(delegate); }); it(@"should receive -valueForKeyPath: and return the stubbed value", ^{ fake stub_method(@selector(valueForKeyPath:)).with(@"delegate").and_return(delegate); [fake valueForKeyPath:@"delegate"] should be_same_instance_as(delegate); }); }); }); }); }); describe(@"trying to create a fake for multiple classes", ^{ it(@"should fail with a reasonable message", ^{ ^{ nice_fake_for([SimpleIncrementer class], [NSValue class]); } should raise_exception.with_reason(@"Can't create a fake for multiple classes."); }); }); }); SPEC_END ================================================ FILE: Spec/Doubles/CDRProtocolFakeSpec.mm ================================================ #import "Cedar.h" #import #import "SimpleIncrementer.h" #import "SimpleMultiplier.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRProtocolFakeSpec) sharedExamplesFor(@"a Cedar protocol fake", ^(NSDictionary *sharedContext) { __block id fake; beforeEach(^{ fake = [sharedContext objectForKey:@"double"]; }); describe(@"-respondsToSelector:", ^{ context(@"when an instance method is required", ^{ it(@"should return true", ^{ fake should respond_to(@selector(value)); }); }); context(@"when an instance method is not defined", ^{ it(@"should return false", ^{ SEL wibble_wobbleSelector = NSSelectorFromString(@"wibble_wobble"); fake should_not respond_to(wibble_wobbleSelector); }); }); }); describe(@"-conformsToProtocol:", ^{ it(@"should be true for the faked protocol", ^{ [fake conformsToProtocol:@protocol(SimpleIncrementer)] should be_truthy; }); it(@"should be true for protocols inherited by the faked protocol", ^{ [fake conformsToProtocol:@protocol(InheritedProtocol)] should be_truthy; }); it(@"should not be true for other protocols", ^{ [fake conformsToProtocol:@protocol(CedarDouble)] should_not be_truthy; [fake conformsToProtocol:@protocol(NSCoding)] should_not be_truthy; }); }); describe(@"stubbing methods not included in the faked protocol(s)", ^{ it(@"should blow up", ^{ ^{ fake stub_method(@selector(addObject:)); } should raise_exception; }); }); describe(@"rejecting methods not included in the faked protocol(s)", ^{ it(@"should blow up", ^{ ^{ fake reject_method(@selector(addObject:)); } should raise_exception; }); }); }); describe(@"fake (protocol)", ^{ describe(@"fake_for(Protocol)", ^{ __block id fake; beforeEach(^{ fake = fake_for(@protocol(SimpleIncrementer)); [[CDRSpecHelper specHelper].sharedExampleContext setObject:fake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar protocol fake"); itShouldBehaveLike(@"a Cedar ordinary fake"); context(@"when calling a method which has not been stubbed", ^{ it(@"should raise an exception", ^{ ^{ [fake value]; } should raise_exception; }); }); context(@"when calling an optional protocol method", ^{ it(@"should raise an exception", ^{ ^{ [fake whatIfIIncrementedBy:2]; } should raise_exception; }); }); describe(@"-description", ^{ it(@"should return the description of the faked protocol", ^{ fake.description should contain(@"Fake implementation of SimpleIncrementer protocol(s)"); }); }); describe(@"handling optional protocol methods", ^{ it(@"should not respond to unstubbed selectors", ^{ fake should_not respond_to(@selector(whatIfIIncrementedBy:)); }); it(@"should raise exception when unstubbed optional method invoked", ^{ ^{ [fake whatIfIIncrementedBy:1]; } should raise_exception; }); context(@"when the method is stubbed", ^{ beforeEach(^{ fake stub_method(@selector(whatIfIIncrementedBy:)).and_return((size_t)42); }); it(@"should respond to its selector", ^{ fake should respond_to(@selector(whatIfIIncrementedBy:)); }); }); }); }); describe(@"nice_fake_for(Protocol)", ^{ __block id nice_fake; beforeEach(^{ nice_fake = nice_fake_for(@protocol(SimpleIncrementer)); [[CDRSpecHelper specHelper].sharedExampleContext setObject:nice_fake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar protocol fake"); itShouldBehaveLike(@"a Cedar nice fake"); describe(@"-description", ^{ it(@"should return the description of the faked protocol", ^{ nice_fake.description should contain(@"Fake implementation of SimpleIncrementer protocol(s)"); }); }); context(@"when calling a method which has not been stubbed", ^{ it(@"should allow method invocation without stubbing", ^{ [nice_fake incrementBy:3]; }); it(@"should default to returning a 0", ^{ expect(nice_fake.aVeryLargeNumber).to(equal(0)); }); it(@"should respond to optional methods", ^{ nice_fake should respond_to(@selector(whatIfIIncrementedBy:)); }); it(@"should record invocations of optional methods", ^{ [nice_fake whatIfIIncrementedBy:7]; nice_fake should have_received(@selector(whatIfIIncrementedBy:)).with(7); }); }); describe(@"rejecting an optional method", ^{ beforeEach(^{ nice_fake reject_method(@selector(whatIfIIncrementedBy:)); }); it(@"should not respond to the method's selector", ^{ nice_fake should_not respond_to(@selector(whatIfIIncrementedBy:)); }); it(@"should raise a helpful exception when the method is called", ^{ ^{ [nice_fake whatIfIIncrementedBy:1]; } should raise_exception.with_reason(@"Received message with explicitly rejected selector "); }); }); }); describe(@"fake_for(Protocol, Protocol, ...)", ^{ __block id fake; beforeEach(^{ fake = fake_for(@protocol(SimpleIncrementer), @protocol(SimpleMultiplier)); [[CDRSpecHelper specHelper].sharedExampleContext setObject:fake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar protocol fake"); itShouldBehaveLike(@"a Cedar ordinary fake"); it(@"should respond to methods from both protocols", ^{ fake should respond_to(@selector(incrementBy:)); fake should respond_to(@selector(multiplyBy:)); }); it(@"should conform to both protocols", ^{ [fake conformsToProtocol:@protocol(SimpleIncrementer)] should equal(YES); [fake conformsToProtocol:@protocol(SimpleMultiplier)] should equal(YES); }); describe(@"-description", ^{ it(@"should return the description of the faked protocols", ^{ fake.description should contain(@"Fake implementation of SimpleIncrementer, SimpleMultiplier protocol(s)"); }); }); context(@"when calling methods that have been stubbed", ^{ beforeEach(^{ fake stub_method(@selector(incrementBy:)); fake stub_method(@selector(multiplyBy:)); }); it(@"should allow invocation of methods from both protocols", ^{ [fake incrementBy:3]; [fake multiplyBy:5]; }); it(@"should record invocations of methods from both protocols", ^{ [fake incrementBy:7]; fake should have_received(@selector(incrementBy:)).with(7); [fake multiplyBy:8]; fake should have_received(@selector(multiplyBy:)).with(8); }); }); }); describe(@"nice_fake_for(Protocol, Protocol, ...)", ^{ __block id nice_fake; beforeEach(^{ nice_fake = nice_fake_for(@protocol(SimpleIncrementer), @protocol(SimpleMultiplier)); [[CDRSpecHelper specHelper].sharedExampleContext setObject:nice_fake forKey:@"double"]; }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); itShouldBehaveLike(@"a Cedar protocol fake"); itShouldBehaveLike(@"a Cedar nice fake"); it(@"should respond to methods from both protocols", ^{ nice_fake should respond_to(@selector(incrementBy:)); nice_fake should respond_to(@selector(multiplyBy:)); }); it(@"should allow method invocation from both protocols without stubbing", ^{ [nice_fake incrementBy:3]; [nice_fake multiplyBy:5]; }); it(@"should conform to both protocols", ^{ [nice_fake conformsToProtocol:@protocol(SimpleIncrementer)] should equal(YES); [nice_fake conformsToProtocol:@protocol(SimpleMultiplier)] should equal(YES); }); it(@"should record invocations of methods from both protocols", ^{ [nice_fake incrementBy:7]; nice_fake should have_received(@selector(incrementBy:)).with(7); [nice_fake multiplyBy:8]; nice_fake should have_received(@selector(multiplyBy:)).with(8); }); describe(@"-description", ^{ it(@"should return the description of the faked protocols", ^{ nice_fake.description should contain(@"Fake implementation of SimpleIncrementer, SimpleMultiplier protocol(s)"); }); }); }); }); SPEC_END ================================================ FILE: Spec/Doubles/CDRSpySpec.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" #import "ObjectWithForwardingTarget.h" #import "ArgumentReleaser.h" #import "ObjectWithProperty.h" #import "SimpleKeyValueObserver.h" #import "ArgumentReleaser.h" #import "ObjectWithValueEquality.h" #import "DeallocNotifier.h" #import "ExpectFailureWithMessage.h" #import "ObjectWithCollections.h" #import "CedarObservedObject.h" #import using namespace Cedar::Matchers; using namespace Cedar::Doubles; using namespace Cedar::Doubles::Arguments; SPEC_BEGIN(SpyOnSpec) describe(@"spy_on", ^{ __block SimpleIncrementer *incrementer; beforeEach(^{ incrementer = [[[SimpleIncrementer alloc] init] autorelease]; spy_on(incrementer); [[CDRSpecHelper specHelper].sharedExampleContext setObject:incrementer forKey:@"double"]; }); describe(@"method stubbing", ^{ NSNumber *arg1 = @1; NSNumber *arg2 = @2; NSNumber *arg3 = @3; NSNumber *returnValue = @4; context(@"with a specific argument value", ^{ context(@"when invoked with a parameter of non-matching value", ^{ beforeEach(^{ incrementer stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValue); }); it(@"should not raise an exception", ^{ ^{ [incrementer methodWithNumber1:arg1 andNumber2:arg3]; } should_not raise_exception; }); it(@"should invoke the original method", ^{ [incrementer methodWithNumber1:arg1 andNumber2:arg3] should equal(@([arg1 floatValue] * [arg3 floatValue])); }); }); }); context(@"with a nil argument", ^{ beforeEach(^{ incrementer stub_method("incrementByNumber:").with(nil); }); context(@"when invoked with a non-nil argument", ^{ beforeEach(^{ [incrementer incrementByNumber:@123]; }); it(@"should invoke the original method", ^{ incrementer.value should equal(123); }); }); }); context(@"with an argument specified as any instance of a specified class", ^{ NSNumber *arg = @123; beforeEach(^{ incrementer stub_method("methodWithNumber1:andNumber2:").with(any([NSDecimalNumber class]), arg).and_return(@99); }); context(@"when invoked with the incorrect class", ^{ it(@"should invoke the original method", ^{ [incrementer methodWithNumber1:@2 andNumber2:arg] should equal(@(2 * [arg floatValue])); }); }); context(@"when invoked with nil", ^{ it(@"should invoke the original method", ^{ [incrementer methodWithNumber1:nil andNumber2:arg] should equal(@0); }); }); }); context(@"with an argument specified as any instance conforming to a specified protocol", ^{ NSNumber *arg = @123; beforeEach(^{ incrementer stub_method("methodWithNumber1:andNumber2:").with(any(@protocol(InheritedProtocol)), arg).and_return(@99); }); context(@"when invoked with the incorrect class", ^{ it(@"should invoke the original method", ^{ [incrementer methodWithNumber1:@2 andNumber2:arg] should equal(@(2 * [arg floatValue])); }); }); context(@"when invoked with nil", ^{ it(@"should invoke the original method", ^{ [incrementer methodWithNumber1:nil andNumber2:arg] should equal(@0); }); }); }); }); describe(@"method spying", ^{ context(@"with an argument that is released by the observed method", ^{ it(@"should retain the argument", ^{ ArgumentReleaser *releaser = [[[ArgumentReleaser alloc] init] autorelease]; spy_on(releaser); ArgumentReleaser *citizen = [[ArgumentReleaser alloc] init]; [releaser releaseArgument:citizen]; citizen should_not be_nil; releaser should have_received(@selector(releaseArgument:)).with(citizen); }); }); }); itShouldBehaveLike(@"a Cedar double"); itShouldBehaveLike(@"a Cedar double when used with ARC"); it(@"should blow up in an obvious manner when spying on nil", ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" ^{ spy_on(nil); } should raise_exception.with_reason(@"Cannot spy on nil"); #pragma clang diagnostic pop }); it(@"should not change the functionality of the given object", ^{ [incrementer increment]; incrementer.value should equal(1); }); it(@"should not change the methods the given object responds to", ^{ SEL wibbleSelector = NSSelectorFromString(@"wibble"); [incrementer respondsToSelector:@selector(increment)] should be_truthy; [incrementer respondsToSelector:wibbleSelector] should_not be_truthy; }); it(@"should not affect other instances of the same class", ^{ [object_getClass(incrementer) conformsToProtocol:@protocol(CedarDouble)] should be_truthy; id other_incrementer = [[[SimpleIncrementer alloc] init] autorelease]; [object_getClass(other_incrementer) conformsToProtocol:@protocol(CedarDouble)] should_not be_truthy; }); it(@"should record messages sent to the object", ^{ incrementer should_not have_received("increment"); [incrementer increment]; incrementer should have_received("increment"); }); describe(@"class identity", ^{ it(@"-isKindOfClass: should work as expected", ^{ [incrementer isKindOfClass:[SimpleIncrementer class]] should be_truthy; [incrementer isKindOfClass:[NSObject class]] should be_truthy; }); it(@"-class should return original class", ^{ [incrementer class] should equal([SimpleIncrementer class]); }); }); it(@"should record messages sent by the object to itself", ^{ [incrementer incrementBy:7]; incrementer should have_received("setValue:"); }); it(@"should raise a meaningful error when sent an unrecognized message", ^{ NSString *expectedReason = [NSString stringWithFormat:@"-[SimpleIncrementer rangeOfComposedCharacterSequenceAtIndex:]: unrecognized selector sent to spy %p", incrementer]; ^{ [(id)incrementer rangeOfComposedCharacterSequenceAtIndex:0]; } should raise_exception.with_reason(expectedReason); }); it(@"should return the description of the spied-upon object", ^{ incrementer.description should contain(@"SimpleIncrementer"); }); describe(@"spying on an object that uses value-based equality checking", ^{ __block ObjectWithValueEquality *ordinaryObject, *spiedObject, *anotherSpiedObject; beforeEach(^{ ordinaryObject = [[[ObjectWithValueEquality alloc] initWithInteger:42] autorelease]; spiedObject = [[[ObjectWithValueEquality alloc] initWithInteger:42] autorelease]; anotherSpiedObject = [[[ObjectWithValueEquality alloc] initWithInteger:42] autorelease]; spy_on(spiedObject); spy_on(anotherSpiedObject); }); it(@"should report equality correctly", ^{ [spiedObject isEqual:ordinaryObject] should be_truthy; [ordinaryObject isEqual:spiedObject] should be_truthy; [spiedObject isEqual:anotherSpiedObject] should be_truthy; }); it(@"should return the same hash as the ordinary object", ^{ [ordinaryObject hash] should equal([spiedObject hash]); }); }); it(@"should only spy on a given object once" , ^{ [incrementer increment]; spy_on(incrementer); incrementer should have_received("increment"); }); describe(@"spying on an object that supports KVC", ^{ it(@"should forward setValue:forKey:", ^{ [incrementer setValue:@"42" forKey:@"string"]; incrementer should have_received(@selector(setValue:forKey:)).with(@"42", @"string"); incrementer.string should equal(@"42"); }); it(@"should forward valueForKey:", ^{ incrementer.string = @"42"; [incrementer valueForKey:@"string"] should equal(@"42"); incrementer should have_received(@selector(valueForKey:)).with(@"string"); }); }); describe(@"spying on an object with a forwarding target", ^{ __block ObjectWithForwardingTarget *forwardingObject; beforeEach(^{ forwardingObject = [[[ObjectWithForwardingTarget alloc] initWithNumberOfThings:42] autorelease]; spy_on(forwardingObject); }); it(@"should not break message forwarding", ^{ forwardingObject.count should equal(42); }); it(@"should allow stubbing of publicly visible methods, even if forwarded in actual implementation", ^{ forwardingObject stub_method("count").and_return((NSUInteger)666); forwardingObject.count should equal(666); }); it(@"should raise a descriptive exception when a method signature couldn't be resolved", ^{ ^{ forwardingObject stub_method("unforwardedUnimplementedMethod"); } should raise_exception.with_reason([NSString stringWithFormat:@"Attempting to stub method , which double <%@> does not respond to", [forwardingObject description]]); }); }); describe(@"spying on objects under KVO", ^{ __block id observedObject; __block NSString *keyPath; __block SimpleKeyValueObserver *observer; void (^itShouldPlayNiceWithKVO)(void) = ^{ it(@"should not raise exception when adding or removing an observer", ^{ ^{ [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; [observedObject removeObserver:observer forKeyPath:keyPath context:NULL]; } should_not raise_exception; }); it(@"should not raise exception when adding or removing an observer", ^{ ^{ [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; [observedObject removeObserver:observer forKeyPath:keyPath context:NULL]; } should_not raise_exception; }); it(@"should correctly record adding and removing an observer", ^{ observedObject should_not have_received("addObserver:forKeyPath:options:context:"); observedObject should_not have_received("removeObserver:forKeyPath:context:"); [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; observedObject should have_received("addObserver:forKeyPath:options:context:"); [observedObject removeObserver:observer forKeyPath:keyPath context:NULL]; observedObject should have_received("removeObserver:forKeyPath:context:"); }); it(@"should record shorthand method for removing an observer", ^{ observedObject should_not have_received("removeObserver:forKeyPath:"); [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; [observedObject removeObserver:observer forKeyPath:keyPath]; observedObject should have_received("removeObserver:forKeyPath:"); }); it(@"should not prevent existing observers from recording observations after they are spied upon", ^{ [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; spy_on(observer); [observedObject mutateObservedProperty]; observer should have_received("observeValueForKeyPath:ofObject:change:context:"); [observedObject removeObserver:observer forKeyPath:keyPath]; }); it(@"should correctly notify other non-spy observers when an existing observer is spied", ^{ SimpleKeyValueObserver *neutralObserver = [[[SimpleKeyValueObserver alloc] init] autorelease]; [observedObject addObserver:neutralObserver forKeyPath:keyPath options:0 context:NULL]; [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; spy_on(observer); [observedObject mutateObservedProperty]; neutralObserver.lastObservedKeyPath should equal(keyPath); [observedObject removeObserver:neutralObserver forKeyPath:keyPath]; [observedObject removeObserver:observer forKeyPath:keyPath]; }); it(@"should not notify observers method after being removed", ^{ [observedObject addObserver:observer forKeyPath:keyPath options:0 context:NULL]; [observedObject removeObserver:observer forKeyPath:keyPath]; spy_on(observer); [observedObject mutateObservedProperty]; observer should_not have_received("observeValueForKeyPath:ofObject:change:context:"); }); }; context(@"with a KVO on a simple property", ^{ beforeEach(^{ keyPath = @"floatProperty"; observedObject = [[[ObjectWithProperty alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with KVO on an array property", ^{ beforeEach(^{ keyPath = @"array"; observedObject = [[[ObjectWithCollections alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with KVO on a set property", ^{ beforeEach(^{ keyPath = @"set"; observedObject = [[[ObjectWithCollections alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with KVO on an ordered set property", ^{ beforeEach(^{ keyPath = @"orderedSet"; observedObject = [[[ObjectWithCollections alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with a KVO on a simple manual property", ^{ beforeEach(^{ keyPath = @"manualFloatProperty"; observedObject = [[[ObjectWithProperty alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with KVO on a manual array", ^{ beforeEach(^{ keyPath = @"manualArray"; observedObject = [[[ObjectWithCollections alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); context(@"with KVO on a manual set", ^{ beforeEach(^{ keyPath = @"manualSet"; observedObject = [[[ObjectWithCollections alloc] init] autorelease]; spy_on(observedObject); observer = [[[SimpleKeyValueObserver alloc] init] autorelease]; }); itShouldPlayNiceWithKVO(); }); }); it(@"should allow spied upon objects to deallocate normally", ^{ __block BOOL wasCalled = NO; DeallocNotifier *notifier = [[DeallocNotifier alloc] initWithNotificationBlock:^{ wasCalled = YES; }]; spy_on(notifier); [notifier release]; wasCalled should be_truthy; }); describe(@"spying on a class", ^{ __block NSFileManager *fileManager; beforeEach(^{ fileManager = nice_fake_for([NSFileManager class]); spy_on([NSFileManager class]); [NSFileManager class] stub_method(@selector(defaultManager)).and_return(fileManager); }); it(@"should work for stubbing methods", ^{ [NSFileManager defaultManager] should be_same_instance_as(fileManager); }); it(@"should reset state between tests", ^{ [(id)[NSFileManager defaultManager] sent_messages] should be_empty; }); }); }); describe(@"stop_spying_on", ^{ it(@"should blow up in an obvious manner when spying on nil", ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" ^{ stop_spying_on(nil); } should raise_exception.with_reason(@"Cannot stop spying on nil"); #pragma clang diagnostic pop }); it(@"should fail gracefully for an object that is not being spied upon", ^{ NSObject *object = [[NSObject new] autorelease]; ^{ stop_spying_on(object); } should_not raise_exception; }); }); SPEC_END ================================================ FILE: Spec/Doubles/CedarDoubleARCSharedExamples.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" #if !__has_feature(objc_arc) #error This spec must be compiled with ARC to work properly #endif using namespace Cedar::Matchers; using namespace Cedar::Doubles; SHARED_EXAMPLE_GROUPS_BEGIN(CedarDoubleARCSharedExamples) sharedExamplesFor(@"a Cedar double when used with ARC", ^(NSDictionary *sharedContext) { __block id myDouble; beforeEach(^{ myDouble = [sharedContext objectForKey:@"double"]; }); context(@"when recording an invocation", ^{ context(@"inside an async block", ^{ it(@"should complete happily", ^{ __block bool called = false; myDouble stub_method("methodWithBlock:").and_do(^(NSInvocation *invocation) { void (^runBlock)(); [invocation getArgument:&runBlock atIndex:2]; runBlock(); called = true; }); dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_group_async(group, queue, ^{ dispatch_group_enter(group); [myDouble methodWithBlock:^{ dispatch_group_leave(group); }]; }); dispatch_group_notify(group, queue, ^{ [myDouble methodWithBlock:^{ }]; }); while (!called) { NSDate *futureDate = [NSDate dateWithTimeIntervalSinceNow:0.1]; [[NSRunLoop currentRunLoop] runUntilDate:futureDate]; } myDouble should have_received("methodWithBlock:"); [myDouble reset_sent_messages]; }); }); }); }); SHARED_EXAMPLE_GROUPS_END ================================================ FILE: Spec/Doubles/CedarDoubleSharedExamples.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" #import "StubbedMethod.h" #import "CedarDoubleImpl.h" #import "FooSuperclass.h" SHARED_EXAMPLE_GROUPS_BEGIN(CedarDoubleSharedExamples) using namespace Cedar::Matchers; using namespace Cedar::Doubles; using namespace Cedar::Doubles::Arguments; sharedExamplesFor(@"a Cedar double", ^(NSDictionary *sharedContext) { __block id myDouble; beforeEach(^{ myDouble = [sharedContext objectForKey:@"double"]; }); describe(@"sent_messages", ^{ beforeEach(^{ myDouble stub_method("value"); [myDouble value]; }); it(@"should have one recording per message sent", ^{ [[myDouble sent_messages] count] should equal(1); }); }); describe(@"sent_messages_with_selector", ^{ beforeEach(^{ myDouble stub_method("incrementBy:"); myDouble stub_method("incrementByInteger:"); [myDouble incrementByInteger:1]; [myDouble incrementBy:2]; [myDouble incrementByInteger:3]; [myDouble incrementBy:4]; [myDouble incrementByInteger:5]; }); it(@"should return all invocations for messages sent that match the given selector", ^{ NSArray *sentMessages = [myDouble sent_messages_with_selector:@selector(incrementBy:)]; sentMessages.count should equal(2); NSInvocation *firstInvocation = sentMessages.firstObject; firstInvocation.selector should equal(@selector(incrementBy:)); NSUInteger firstIncrement; [firstInvocation getArgument:&firstIncrement atIndex:2]; firstIncrement should equal(2); NSInvocation *secondInvocation = sentMessages.lastObject; secondInvocation.selector should equal(@selector(incrementBy:)); NSUInteger secondIncrement; [secondInvocation getArgument:&secondIncrement atIndex:2]; secondIncrement should equal(4); }); }); context(@"where the expected type is a char * and a char * is passed", ^{ it(@"should just work", ^{ ^{ myDouble stub_method("methodWithCString:").with("hello"); } should_not raise_exception; }); }); describe(@"reset_sent_messages", ^{ beforeEach(^{ myDouble stub_method("value"); [myDouble value]; myDouble should have_received("value"); [myDouble reset_sent_messages]; }); it(@"should remove any previously recorded invocations", ^{ myDouble should_not have_received("value"); }); }); context(@"when recording an invocation", ^{ it(@"should release the invocations retaining the double in afterEach", ^{ static NSInteger numInvocations = 2; myDouble stub_method("value"); NSUInteger doubleRetainCount = myDouble.retainCount; // spies are allowed to increment the retain count of the double by 1 // but should hand the retain over to the autorelease pool @autoreleasepool { for (NSInteger invocation = 0; invocation < numInvocations; ++invocation) { [myDouble value]; } } myDouble.retainCount should equal(doubleRetainCount + numInvocations); [CedarDoubleImpl class] should conform_to(@protocol(CDRHooks)); [CedarDoubleImpl afterEach]; myDouble.retainCount should equal(doubleRetainCount); }); it(@"should exchange any block arguments with copies that can later be invoked", ^{ __block BOOL blockWasCalled = NO; void *blockVariableLocationOnStack = &blockWasCalled; myDouble stub_method("methodWithBlock:"); ^{ void(^originalBlock)() = ^{ blockWasCalled = YES; }; [myDouble methodWithBlock:originalBlock]; }(); NSInvocation *invocationWithBlock = [[myDouble sent_messages] lastObject]; void(^retrievedBlock)() = nil; [invocationWithBlock getArgument:&retrievedBlock atIndex:2]; //Blocks don't change memory address when copied but we can detect copying //by observing when it's enclosed block variables are moved to the heap. //See: http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html (void *)&blockWasCalled should_not equal(blockVariableLocationOnStack); retrievedBlock(); blockWasCalled should be_truthy; }); it(@"should exchange any c-string arguments with copies that can later be accessed", ^{ char *string = (char *)malloc(6); strcpy(string, "hello"); myDouble stub_method("methodWithCString:"); [myDouble methodWithCString:string]; strcpy(string, "byeby"); NSInvocation *invocation = [[myDouble sent_messages] lastObject]; char *argument = NULL; [invocation getArgument:&argument atIndex:2]; argument == string should_not be_truthy; strcmp("hello", argument) should equal(0); free(string); }); }); describe(@"-stub_method", ^{ context(@"with a non-double", ^{ it(@"should raise an exception", ^{ NSObject *non_double = [[[NSObject alloc] init] autorelease]; ^{ non_double stub_method("description"); } should raise_exception.with_reason([NSString stringWithFormat:@"%@ is not a double", non_double]); }); }); context(@"with a method name that the stub does not respond to", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("wibble_wobble"); } should raise_exception.with_reason([NSString stringWithFormat:@"Attempting to stub method , which double <%@> does not respond to", myDouble]); }); }); context(@"with a method with no arguments", ^{ context(@"when stubbed twice", ^{ it(@"should raise an exception with a helpful message", ^{ myDouble stub_method("value"); ^{ myDouble stub_method("value"); } should raise_exception.with_reason(@"The method is already stubbed with arguments () - use again() to override"); }); it(@"should allow the method to be stubbed again when again() is called", ^{ myDouble stub_method("value"); myDouble stub_method("value").again(); }); it(@"should blow up when again() is called when not previously stubbed", ^{ ^{ myDouble stub_method("value").again(); } should raise_exception.with_reason(@"The method is not stubbed with arguments () - again() should only be used to override a stubbed method."); }); }); context(@"with no return value", ^{ beforeEach(^{ myDouble stub_method("value"); }); it(@"should record the invocation", ^{ [myDouble value]; myDouble should have_received("value"); }); it(@"should return zero", ^{ myDouble.value should equal(0); }); }); context(@"with a return value of the correct type", ^{ size_t someArgument = 1; beforeEach(^{ myDouble stub_method("value").and_return(someArgument); }); it(@"should return the specified return value", ^{ myDouble.value should equal(someArgument); }); }); context(@"with a return value of a type with the wrong binary size", ^{ int someArgument = 1; it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_return(someArgument); } should raise_exception; }); }); context(@"with a return value of an inappropriate type", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_return(@"foo"); } should raise_exception; }); }); }); context(@"when the stub is instructed to raise an exception (and_raise)", ^{ context(@"with no parameter", ^{ beforeEach(^{ myDouble stub_method("increment").and_raise_exception(); }); it(@"should raise a generic exception", ^{ ^{ [myDouble increment]; } should raise_exception([NSException class]); }); }); context(@"with a specified exception", ^{ id someException = @"that's some pig (exception)"; beforeEach(^{ myDouble stub_method("increment").and_raise_exception(someException); }); it(@"should raise that exception instance", ^{ ^{ [myDouble increment]; } should raise_exception(someException); }); }); }); context(@"with a replacement implementation receiving the method's arguments (and_do_block)", ^{ context(@"with a valid block that only has a return value", ^{ __block BOOL implementation_block_called; size_t return_value = 123; beforeEach(^{ implementation_block_called = NO; myDouble stub_method("value").and_do_block(^size_t { implementation_block_called = YES; return return_value; }); }); it(@"should invoke the block", ^{ [myDouble value]; implementation_block_called should be_truthy; }); it(@"should return the value returned from the block", ^{ [myDouble value] should equal(return_value); }); context(@"when combined with an explicit return value", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do_block(^size_t{ return 0; }).and_return(2); } should raise_exception.with_reason(@"Multiple return values specified for "); }); }); context(@"when added after an explicit return value", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_return(2).and_do_block(^size_t{ return 0; }); } should raise_exception.with_reason(@"Multiple return values specified for "); }); }); context(@"when combined with an invocation block", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do_block(^size_t{ return 0; }).and_do(^(NSInvocation *invocation) {}); } should raise_exception.with_reason(@"Multiple blocks specified for "); }); }); context(@"when added after an invocation block", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do(^(NSInvocation *invocation) {}).and_do_block(^size_t{ return 0; }); } should raise_exception.with_reason(@"Multiple blocks specified for "); }); }); }); context(@"with a valid block that has primitive integer arguments", ^{ size_t sent_argument = 2; __block size_t received_argument; beforeEach(^{ received_argument = 0; myDouble stub_method("incrementBy:").and_do_block(^(size_t arg) { received_argument = arg; }); [myDouble incrementBy:sent_argument]; }); it(@"should be passed the correct arguments", ^{ received_argument should equal(sent_argument); }); }); context(@"with a valid block that has primitive floating point arguments", ^{ double sent_argument = 9876.54321; __block double received_argument1, received_argument2; double return_value = 192837.465; beforeEach(^{ received_argument1 = received_argument2 = 0; myDouble stub_method("methodWithDouble1:andDouble2:").and_do_block(^double(double double1, double double2) { received_argument1 = double1; received_argument2 = double2; return return_value; }); [myDouble methodWithDouble1:sent_argument andDouble2:sent_argument]; }); it(@"should be passed the correct arguments", ^{ received_argument1 should equal(sent_argument); received_argument2 should equal(sent_argument); }); it(@"should return the value returned from the block", ^{ [myDouble methodWithDouble1:0 andDouble2:0] should equal(return_value); }); }); context(@"with a valid block that uses large structs", ^{ LargeIncrementerStruct sent_argument = { 1234567, 98765432, 42, SIZE_T_MAX }; __block LargeIncrementerStruct received_argument; LargeIncrementerStruct return_value = { 123, 456, 789, SIZE_T_MAX }; beforeEach(^{ received_argument = {}; myDouble stub_method("methodWithLargeStruct1:andLargeStruct2:").and_do_block(^LargeIncrementerStruct(LargeIncrementerStruct struct1, LargeIncrementerStruct struct2) { received_argument = struct2; return return_value; }); [myDouble methodWithLargeStruct1:sent_argument andLargeStruct2:sent_argument]; }); it(@"should be passed the correct struct arguments", ^{ memcmp(&received_argument, &sent_argument, sizeof(sent_argument)) should equal(0); }); it(@"should return the struct value returned from the block", ^{ LargeIncrementerStruct returned_value = [myDouble methodWithLargeStruct1:sent_argument andLargeStruct2:sent_argument]; memcmp(&return_value, &returned_value, sizeof(return_value)) should equal(0); }); }); context(@"with a valid block that uses objects", ^{ NSNumber *sent_argument = @(M_PI); __block NSNumber *received_argument; NSNumber *return_value = @(42); beforeEach(^{ received_argument = nil; myDouble stub_method("methodWithNumber1:andNumber2:").and_do_block(^NSNumber *(NSNumber *num1, NSNumber *num2) { received_argument = num1; return return_value; }); [myDouble methodWithNumber1:sent_argument andNumber2:sent_argument]; }); it(@"should be passed the correct object arguments", ^{ received_argument should be_same_instance_as(sent_argument); }); it(@"should return the object value returned from the block", ^{ [myDouble methodWithNumber1:@(1) andNumber2:@(2)] should be_same_instance_as(return_value); }); }); context(@"with a valid block that takes a complex block as a parameter", ^{ ComplexIncrementerBlock sent_argument = ^LargeIncrementerStruct(NSNumber *, LargeIncrementerStruct, id){ return (LargeIncrementerStruct){}; }; __block ComplexIncrementerBlock received_argument; beforeEach(^{ received_argument = nil; myDouble stub_method("methodWithNumber:complexBlock:").and_do_block(^(NSNumber *, ComplexIncrementerBlock block) { received_argument = block; }); [myDouble methodWithNumber:@(1) complexBlock:sent_argument]; }); it(@"should be passed the correct block argument", ^{ received_argument should equal(sent_argument); }); }); context(@"with something not a block", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do_block(@(2)); } should raise_exception.with_reason([NSString stringWithFormat:@"Attempted to stub and do a block that isn't a block for "]); }); }); context(@"with a block that does not match the method's return type", ^{ void (^invalidBlock)(NSString *) = ^(NSString *){}; it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithString:").and_do_block(invalidBlock); } should raise_exception.with_reason(@"Invalid return type 'void' instead of 'id' for "); }); }); context(@"with a block that has a different number of arguments than the method", ^{ void (^invalidBlock)(void) = ^{}; it(@"should raise an exception", ^{ ^{ myDouble stub_method("incrementBy:").and_do_block(invalidBlock); } should raise_exception.with_reason(@"Wrong number of parameters for ; expected: 1; actual: 0 (not counting the special first parameter, `id self`)"); }); }); context(@"with a block that has a different argument type than the method", ^{ void (^invalidBlock)(float) = ^(float){}; it(@"should raise an exception", ^{ ^{ myDouble stub_method("incrementByNumber:").and_do_block(invalidBlock); } should raise_exception.with_reason(@"Found argument type 'float', expected 'id'; argument #1 for "); }); }); }); context(@"with a replacement implementation receiving an invocation (and_do)", ^{ __block BOOL replacement_invocation_called; __block size_t sent_argument = 2, received_argument; __block size_t return_value; beforeEach(^{ replacement_invocation_called = NO; return_value = 123; myDouble stub_method("incrementBy:").and_do(^(NSInvocation *invocation) { replacement_invocation_called = YES; [invocation getArgument:&received_argument atIndex:2]; }); myDouble stub_method("value").and_do(^(NSInvocation *invocation) { [invocation setReturnValue:&return_value]; }); [myDouble incrementBy:sent_argument]; }); it(@"should invoke the block", ^{ replacement_invocation_called should be_truthy; }); it(@"should receive the correct arguments in the invocation", ^{ received_argument should equal(sent_argument); }); it(@"should return the value provided by the NSInvocation", ^{ [myDouble value] should equal(return_value); }); context(@"when combined with an explicit return value", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do(^(NSInvocation *invocation) {}).and_return(2); } should raise_exception.with_reason(@"Multiple return values specified for "); }); }); context(@"when added after an explicit return value", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_return(2).and_do(^(NSInvocation *invocation) {}); } should raise_exception.with_reason(@"Multiple return values specified for "); }); }); context(@"when combined with an implementation block", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do(^(NSInvocation *invocation) {}).and_do_block(^size_t{ return 0; }); } should raise_exception.with_reason(@"Multiple blocks specified for "); }); }); context(@"when added after an implementation block", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").and_do_block(^size_t{ return 0; }).and_do(^(NSInvocation *invocation) {}); } should raise_exception.with_reason(@"Multiple blocks specified for "); }); }); }); describe(@"argument expectations", ^{ describe(@"when stubbing the same method multiple times", ^{ context(@"with distinctly different arguments", ^{ context(@"primitive arguments", ^{ __block BOOL firstStubWasCalled, secondStubWasCalled; beforeEach(^{ firstStubWasCalled = secondStubWasCalled = NO; myDouble stub_method("incrementByInteger:").with(1).and_do(^(NSInvocation *) { firstStubWasCalled = YES; }); myDouble stub_method("incrementByInteger:").with(3).and_do(^(NSInvocation *) { secondStubWasCalled = YES; }); }); it(@"should perform the stub action associated with those arguments when invoked with those arguments", ^{ [myDouble incrementByInteger:3]; secondStubWasCalled should be_truthy; firstStubWasCalled should_not be_truthy; }); }); context(@"object arguments", ^{ NSNumber *arg1 = @1; NSNumber *arg2 = @2; NSNumber *returnValue1 = @3; NSNumber *arg3 = @88; NSNumber *returnValue2 = @42; __block void(^stubMethodAgainWithDifferentArugmentsBlock)(); beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValue1); stubMethodAgainWithDifferentArugmentsBlock = [^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg3).and_return(returnValue2); } copy]; }); afterEach(^{ [stubMethodAgainWithDifferentArugmentsBlock release]; }); it(@"should not raise an exception", ^{ stubMethodAgainWithDifferentArugmentsBlock should_not raise_exception; }); context(@"when invoked", ^{ beforeEach(^{ stubMethodAgainWithDifferentArugmentsBlock(); }); it(@"should return the value associated with the corresponding arguments", ^{ [myDouble methodWithNumber1:arg1 andNumber2:arg2] should equal(returnValue1); [myDouble methodWithNumber1:arg1 andNumber2:arg3] should equal(returnValue2); }); }); }); }); context(@"with the same arguments", ^{ context(@"primitive arguments", ^{ NSInteger arg1 = 1; it(@"should raise an exception", ^{ myDouble stub_method("incrementByInteger:").with(arg1); ^{ myDouble stub_method("incrementByInteger:").with(arg1); } should raise_exception.with_reason(@"The method is already stubbed with arguments (<1>) - use again() to override"); }); }); context(@"object arguments", ^{ NSNumber *arg1 = @1; NSNumber *arg2 = @2; NSNumber *returnValue1 = @3; NSNumber *returnValue2 = @4; it(@"should raise an exception", ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValue1); ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(@91); } should raise_exception.with_reason(@"The method is already stubbed with arguments (<1><2>) - use again() to override"); }); it(@"should allow re-stubbing with the new return value when again() is called", ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValue1); myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).again().and_return(returnValue2); [myDouble methodWithNumber1:arg1 andNumber2:arg2] should equal(returnValue2); }); }); }); context(@"with no arguments, then the anything argument", ^{ it(@"should raise an exception", ^{ myDouble stub_method("incrementByInteger:"); ^{ myDouble stub_method("incrementByInteger:").with(Arguments::anything); } should raise_exception; }); }); context(@"with the anything argument, then with no arguments", ^{ it(@"should raise an exception", ^{ myDouble stub_method("incrementByInteger:").with(Arguments::anything); ^{ myDouble stub_method("incrementByInteger:"); } should raise_exception; }); }); context(@"with the anything argument in different positions", ^{ beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(@1, Arguments::anything).and_return(@1); myDouble stub_method("methodWithNumber1:andNumber2:").with(Arguments::anything, @2).and_return(@2); }); it(@"should choose the correct stub to invoke based on the specific arguments", ^{ [myDouble methodWithNumber1:@1 andNumber2:@3] should equal(@1); [myDouble methodWithNumber1:@3 andNumber2:@2] should equal(@2); }); it(@"should choose the most recent stub if more than one stub matches ", ^{ [myDouble methodWithNumber1:@1 andNumber2:@2] should equal(@2); }); it(@"should choose the overridden stub if more than one stub matches", ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(Arguments::anything, @2).again().and_return(@3); [myDouble methodWithNumber1:@3 andNumber2:@2] should equal(@3); myDouble stub_method("methodWithNumber1:andNumber2:").with(@1, Arguments::anything).again().and_return(@4); [myDouble methodWithNumber1:@1 andNumber2:@3] should equal(@4); }); }); context(@"with an 'any instance of' argument", ^{ __block void(^stubMethodAgainWithNoArgumentsBlock)(); __block void(^stubMethodAgainWithAnyInstanceOfClassArgumentBlock)(); __block void(^stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock)(); __block FooSuperclass *specificInstance; __block BarSubclass *specificBarInstance; beforeEach(^{ specificInstance = [[[FooSuperclass alloc] init] autorelease]; specificBarInstance = [[[BarSubclass alloc] init] autorelease]; myDouble stub_method("methodWithFooSuperclass:").with(specificInstance).and_return(@"foo"); myDouble stub_method("methodWithFooSuperclass:").with(specificBarInstance).and_return(@"bar_specific"); stubMethodAgainWithNoArgumentsBlock = [^{ myDouble stub_method("methodWithFooSuperclass:").and_return(@"quux"); } copy]; stubMethodAgainWithAnyInstanceOfClassArgumentBlock = [^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any([BarSubclass class])).and_return(@"bar"); } copy]; stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock = [^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any(@protocol(BazProtocol))).and_return(@"baz"); } copy]; }); afterEach(^{ [stubMethodAgainWithNoArgumentsBlock release]; [stubMethodAgainWithAnyInstanceOfClassArgumentBlock release]; [stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock release]; }); it(@"should not raise an exception", ^{ stubMethodAgainWithNoArgumentsBlock should_not raise_exception; stubMethodAgainWithAnyInstanceOfClassArgumentBlock should_not raise_exception; stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock should_not raise_exception; }); context(@"with another 'any instance of class' argument", ^{ beforeEach(^{ stubMethodAgainWithAnyInstanceOfClassArgumentBlock(); }); context(@"of the same class", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any([BarSubclass class])).and_return(@"bar2"); } should raise_exception.with_reason(@"The method is already stubbed with arguments () - use again() to override"); }); }); context(@"of a different class", ^{ beforeEach(^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any([QuuxSubclass class])).and_return(@"any_quux"); }); context(@"when invoked", ^{ it(@"should match the stub for the correct 'any instance of' class", ^{ [myDouble methodWithFooSuperclass:[[[QuuxSubclass alloc] init] autorelease]] should equal(@"any_quux"); }); }); }); }); context(@"with another 'any instance conforming to protocol' argument", ^{ beforeEach(^{ stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock(); }); context(@"with the same protocol", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any(@protocol(BazProtocol))).and_return(@"baz2"); } should raise_exception.with_reason(@"The method is already stubbed with arguments () - use again() to override"); }); }); context(@"with a different protocol", ^{ beforeEach(^{ myDouble stub_method("methodWithFooSuperclass:").with(Arguments::any(@protocol(NSObject))).and_return(@"any_object"); }); context(@"when invoked", ^{ it(@"should match the stub for the correct protocol", ^{ [myDouble methodWithFooSuperclass:[[[QuuxSubclass alloc] init] autorelease]] should equal(@"any_object"); }); }); }); }); context(@"when invoked", ^{ beforeEach(^{ stubMethodAgainWithNoArgumentsBlock(); stubMethodAgainWithAnyInstanceOfClassArgumentBlock(); stubMethodAgainWithAnyInstanceConformingToProtocolArgumentBlock(); }); it(@"should match the stub for specific instances", ^{ [myDouble methodWithFooSuperclass:specificInstance] should equal(@"foo"); [myDouble methodWithFooSuperclass:specificBarInstance] should equal(@"bar_specific"); }); it(@"should match the stub for Arguments::any()", ^{ [myDouble methodWithFooSuperclass:[[[BarSubclass alloc] init] autorelease]] should equal(@"bar"); [myDouble methodWithFooSuperclass:[[[FooSuperclass alloc] init] autorelease]] should equal(@"quux"); [myDouble methodWithFooSuperclass:[[[QuuxSubclass alloc] init] autorelease]] should equal(@"baz"); }); it(@"should match the unqualified stub", ^{ [myDouble methodWithFooSuperclass:nil] should equal(@"quux"); }); }); }); }); context(@"when specified with .with(varargs)", ^{ NSNumber *arg1 = @1;; NSNumber *arg2 = @2; NSNumber *arg3 = @3; NSNumber *returnValue = @99; context(@"with the incorrect number of arguments", ^{ it(@"should raise an exception when invoked with too few arguments", ^{ NSString *reason = @"Wrong number of expected parameters for ; expected: 1, actual: 2"; ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1).and_return(returnValue); } should raise_exception.with_reason(reason); }); it(@"should raise an exception when invoked with too many arguments", ^{ NSString *reason = @"Wrong number of expected parameters for ; expected: 3, actual: 2"; ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2, arg3).and_return(returnValue); } should raise_exception.with_reason(reason); }); }); context(@"with the correct number of arguments", ^{ context(@"of the correct types", ^{ beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValue); }); context(@"when invoked with a parameters of the expected value", ^{ it(@"should return the returnValue", ^{ [myDouble methodWithNumber1:arg1 andNumber2:arg2] should equal(returnValue); }); }); }); context(@"of incorrect types", ^{ NSString *reason = @"Attempt to compare expected argument <10> of type 'int' with actual argument type 'id'; argument #2 for "; it(@"should raise an exception", ^{ int invalidInt = 10; ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, invalidInt); } should raise_exception.with_reason(reason); }); }); }); }); context(@"when specified with .with().and_with()", ^{ context(@"with too few", ^{ unsigned int expectedIncrementValue = 1; NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for ; expected: 1, actual: 2"]; it(@"should raise an exception", ^{ ^{ myDouble stub_method("incrementByABit:andABitMore:").with(expectedIncrementValue); } should raise_exception.with_reason(reason); }); }); context(@"with too many", ^{ NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for ; expected: 1, actual: 0"]; it(@"should raise an exception", ^{ ^{ myDouble stub_method("value").with(@"foo"); } should raise_exception.with_reason(reason); }); }); context(@"with the correct number", ^{ NSNumber *expectedBitMoreValue = @10; context(@"of the correct types", ^{ unsigned int expectedIncrementValue = 1; beforeEach(^{ myDouble stub_method("incrementByABit:andABitMore:").with(expectedIncrementValue).and_with(expectedBitMoreValue); }); context(@"when invoked with a parameter of the expected value", ^{ it(@"should not raise an exception", ^{ [myDouble incrementByABit:expectedIncrementValue andABitMore:expectedBitMoreValue]; }); }); }); context(@"of incorrect types", ^{ context(@"where the incorrect type is an object", ^{ it(@"should raise an exception", ^{ NSString *incorrectType = @"your mom"; NSString *reason = [NSString stringWithFormat:@"Attempt to compare expected argument <%@> of type 'id' with actual argument type 'unsigned int'; argument #1 for ", incorrectType]; ^{ myDouble stub_method("incrementByABit:andABitMore:").with(incorrectType).and_with(expectedBitMoreValue); } should raise_exception.with_reason(reason); }); }); context(@"where the incorrect type is a char *", ^{ it(@"should raise an exception", ^{ NSString *reason = [NSString stringWithFormat:@"Attempt to compare expected argument of type 'char *' with actual argument type 'unsigned int'; argument #1 for ", "your mom"]; ^{ myDouble stub_method("incrementByABit:andABitMore:").with((char *)"your mom").and_with(expectedBitMoreValue); } should raise_exception.with_reason(reason); }); }); context(@"where the incorrect type is a non-object, non-cstring pointer", ^{ it(@"should raise an exception", ^{ int anInt = 1; int *ptr = &anInt; NSString *reason = [NSString stringWithFormat:@"Attempt to compare expected argument <%p> of type 'int *' with actual argument type 'unsigned int'; argument #1 for ", ptr]; ^{ myDouble stub_method("incrementByABit:andABitMore:").with(ptr).and_with(expectedBitMoreValue); } should raise_exception.with_reason(reason); }); }); }); }); context(@"with a specific value", ^{ size_t expectedValue = 1; beforeEach(^{ myDouble stub_method("incrementBy:").with(expectedValue); }); context(@"when invoked with an argument of the expected value", ^{ it(@"should record the invocation", ^{ [myDouble incrementBy:expectedValue]; myDouble should have_received("incrementBy:").with(expectedValue); }); }); }); context(@"with nil", ^{ __block BOOL stubbedBehaviorWasInvoked; beforeEach(^{ stubbedBehaviorWasInvoked = NO; myDouble stub_method("incrementByNumber:").with(nil).and_do(^(NSInvocation *) { stubbedBehaviorWasInvoked = YES; }); }); context(@"when invoked with a nil argument", ^{ beforeEach(^{ [myDouble incrementByNumber:nil]; }); it(@"should record the invocation", ^{ myDouble should have_received("incrementByNumber:").with(nil); }); it(@"should invoke the stubbed behavior", ^{ stubbedBehaviorWasInvoked should be_truthy; }); }); }); context(@"with id-typed nil", ^{ __block BOOL stubbedBehaviorWasInvoked; beforeEach(^{ stubbedBehaviorWasInvoked = NO; myDouble stub_method("incrementByNumber:").with((id)nil).and_do(^(NSInvocation *) { stubbedBehaviorWasInvoked = YES; }); }); context(@"when invoked with a nil argument", ^{ beforeEach(^{ [myDouble incrementByNumber:nil]; }); it(@"should record the invocation", ^{ myDouble should have_received("incrementByNumber:").with((id)nil); }); it(@"should invoke the stubbed behavior", ^{ stubbedBehaviorWasInvoked should be_truthy; }); }); }); context(@"with a non-object non-char pointer, when invoked with the argument", ^{ __block BOOL stubbedBehaviorWasInvoked; __block int *pointerToPrimitivePointer; beforeEach(^{ int primitive = 42; stubbedBehaviorWasInvoked = NO; myDouble stub_method(@selector(methodWithPrimitivePointerArgument:)).with(&primitive).and_do(^(NSInvocation *) { stubbedBehaviorWasInvoked = YES; }); [myDouble methodWithPrimitivePointerArgument:&primitive]; pointerToPrimitivePointer = &primitive; }); it(@"should record the invocation", ^{ myDouble should have_received("methodWithPrimitivePointerArgument:").with(pointerToPrimitivePointer); }); it(@"should invoke the stubbed behavior", ^{ stubbedBehaviorWasInvoked should be_truthy; }); }); context(@"with an object pointer, when invoked with the argument", ^{ __block BOOL stubbedBehaviorWasInvoked; __block id *pointerToObjectPointer; beforeEach(^{ NSError *error = [NSError errorWithDomain:@"ImTheTester" code:12345 userInfo:nil]; stubbedBehaviorWasInvoked = NO; myDouble stub_method(@selector(methodWithObjectPointerArgument:)).with(&error).and_do(^(NSInvocation *) { stubbedBehaviorWasInvoked = YES; }); [myDouble methodWithObjectPointerArgument:&error]; myDouble should have_received("methodWithObjectPointerArgument:").with(&error); pointerToObjectPointer = &error; }); it(@"should record the invocation", ^{ myDouble should have_received("methodWithObjectPointerArgument:").with(pointerToObjectPointer); }); it(@"should invoke the stubbed behavior", ^{ stubbedBehaviorWasInvoked should be_truthy; }); }); context(@"with an argument specified as anything", ^{ NSNumber *arg1 = @3; NSNumber *arg2 = @123; NSNumber *returnValueWithAnythingArg = @99; NSNumber *returnValueWithExplicitArgs = @100; context(@"and the 'anything' method is stubbed first", ^{ beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(anything, arg2).and_return(returnValueWithAnythingArg); myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValueWithExplicitArgs); }); it(@"should allow any value for the 'anything' argument", ^{ [myDouble methodWithNumber1:@8 andNumber2:arg2] should equal(returnValueWithAnythingArg); [myDouble methodWithNumber1:@90210 andNumber2:arg2] should equal(returnValueWithAnythingArg); }); context(@"and stubbing the method again with anything passed for the same parameter as in the stub", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(anything).and_with(arg2).and_return(returnValueWithAnythingArg); } should raise_exception.with_reason(@"The method is already stubbed with arguments (<123>) - use again() to override"); }); }); context(@"when two stubs exist", ^{ it(@"should invoke the more specific stub", ^{ [myDouble methodWithNumber1:arg1 andNumber2:arg2] should equal(returnValueWithExplicitArgs); }); }); }); context(@"and the 'anything' method is stubbed second", ^{ beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(returnValueWithExplicitArgs); myDouble stub_method("methodWithNumber1:andNumber2:").with(anything, arg2).and_return(returnValueWithAnythingArg); }); it(@"should allow any value for the 'anything' argument", ^{ [myDouble methodWithNumber1:@8 andNumber2:arg2] should equal(returnValueWithAnythingArg); [myDouble methodWithNumber1:@90210 andNumber2:arg2] should equal(returnValueWithAnythingArg); }); context(@"and stubbing the method again with anything passed for the same parameter as in the stub", ^{ it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(anything).and_with(arg2).and_return(returnValueWithAnythingArg); } should raise_exception.with_reason(@"The method is already stubbed with arguments (<123>) - use again() to override"); }); }); context(@"when two stubs exist", ^{ it(@"should invoke the more specific stub", ^{ [myDouble methodWithNumber1:arg1 andNumber2:arg2] should equal(returnValueWithExplicitArgs); }); }); }); }); context(@"with an argument specified as any instance of a specified class", ^{ NSNumber *arg = @123; NSNumber *returnValue = @99; beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(any([NSDecimalNumber class]), arg).and_return(returnValue); }); context(@"when invoked with the correct class", ^{ it(@"should return the expected value", ^{ [myDouble methodWithNumber1:[NSDecimalNumber decimalNumberWithDecimal:[@3.14159265359 decimalValue]] andNumber2:arg] should equal(returnValue); }); }); }); context(@"with an argument specified as any instance conforming to a specified protocol", ^{ NSNumber *arg = @123; NSNumber *returnValue = @99; beforeEach(^{ myDouble stub_method("methodWithNumber1:andNumber2:").with(any(@protocol(NSObject)), arg).and_return(returnValue); }); context(@"when invoked with the correct class", ^{ it(@"should return the expected value", ^{ [myDouble methodWithNumber1:[NSDecimalNumber decimalNumberWithDecimal:[@3.14159265359 decimalValue]] andNumber2:arg] should equal(returnValue); }); }); }); }); }); describe(@"return values (and_return)", ^{ context(@"with a value of the correct type", ^{ size_t returnValue = 1729; beforeEach(^{ myDouble stub_method("value").and_return(returnValue); }); it(@"should return the expected value", ^{ [myDouble value] should equal(returnValue); }); }); context(@"with a value of an incorrect type", ^{ unsigned int invalidReturnValue = 3; it(@"should raise an exception", ^{ ^{ myDouble stub_method("methodWithString:").and_return(invalidReturnValue); } should raise_exception.with_reason(@"Invalid return value type 'unsigned int' instead of 'id' for "); }); }); context(@"with an arbitrary struct value", ^{ LargeIncrementerStruct returnValue = {99, 88, 77, 66}; beforeEach(^{ myDouble stub_method("methodWithLargeStruct1:andLargeStruct2:").and_return(returnValue); }); it(@"should return the expected value", ^{ LargeIncrementerStruct returnedValue = [myDouble methodWithLargeStruct1:{} andLargeStruct2:{}]; memcmp(&returnValue, &returnedValue, sizeof(LargeIncrementerStruct)) should equal(0); }); }); context(@"with `nil`", ^{ beforeEach(^{ myDouble stub_method("valueAsNumber").and_return(nil); }); it(@"should return the expected value", ^{ [myDouble valueAsNumber] should be_nil; }); }); }); }); }); SHARED_EXAMPLE_GROUPS_END ================================================ FILE: Spec/Doubles/CedarNiceFakeSharedExamples.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" SHARED_EXAMPLE_GROUPS_BEGIN(CedarNiceFakeSharedExamples) using namespace Cedar::Matchers; using namespace Cedar::Doubles; using namespace Cedar::Doubles::Arguments; sharedExamplesFor(@"a Cedar nice fake", ^(NSDictionary *sharedContext) { __block id myNiceFake; beforeEach(^{ myNiceFake = [sharedContext objectForKey:@"double"]; }); describe(@"method stubbing", ^{ NSNumber *arg1 = @1; NSNumber *arg2 = @2; NSNumber *arg3 = @3; context(@"with a specific argument value", ^{ context(@"when invoked with a parameter of non-matching value", ^{ beforeEach(^{ myNiceFake stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(@4); }); it(@"should not raise an exception", ^{ ^{ [myNiceFake methodWithNumber1:arg1 andNumber2:arg3]; } should_not raise_exception; }); it(@"should return nil", ^{ [myNiceFake methodWithNumber1:arg1 andNumber2:arg3] should be_nil; }); }); }); context(@"with a nil argument", ^{ beforeEach(^{ myNiceFake stub_method("methodWithNumber1:andNumber2:").with(nil, nil); }); context(@"when invoked with a non-nil argument", ^{ it(@"should return nil", ^{ [myNiceFake methodWithNumber1:nil andNumber2:@123] should be_nil; }); }); }); context(@"with an argument specified as any instance of a specified class", ^{ NSNumber *arg = @123; beforeEach(^{ myNiceFake stub_method("methodWithNumber1:andNumber2:").with(any([NSDecimalNumber class]), arg).and_return(@99); }); context(@"when invoked with the correct arguments", ^{ it(@"should return the stubbed value", ^{ [myNiceFake methodWithNumber1:[NSDecimalNumber decimalNumberWithString:@"1.0"] andNumber2:arg] should equal(@99); }); }); context(@"when invoked with the incorrect class", ^{ it(@"should return nil", ^{ [myNiceFake methodWithNumber1:@1 andNumber2:arg] should be_nil; }); }); context(@"when invoked with nil", ^{ it(@"should return nil", ^{ [myNiceFake methodWithNumber1:nil andNumber2:arg] should be_nil; }); }); }); context(@"with an argument specified as any instance conforming to a specified protocol", ^{ beforeEach(^{ myNiceFake stub_method("methodWithInheritedProtocol:").with(any(@protocol(InheritedProtocol))).and_return(@99); }); context(@"when invoked with the correct arguments", ^{ it(@"should return the stubbed value", ^{ SimpleIncrementer *incrementer = [[[SimpleIncrementer alloc] init] autorelease]; [myNiceFake methodWithInheritedProtocol:incrementer] should equal(@99); }); }); context(@"when invoked with the incorrect class", ^{ it(@"should return nil", ^{ NSArray *items = @[@1]; [myNiceFake methodWithInheritedProtocol:[items firstObject]] should be_nil; }); }); context(@"when invoked with nil", ^{ it(@"should return nil", ^{ [myNiceFake methodWithInheritedProtocol:nil] should be_nil; }); }); }); }); }); SHARED_EXAMPLE_GROUPS_END ================================================ FILE: Spec/Doubles/CedarOrdinaryFakeSharedExamples.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" SHARED_EXAMPLE_GROUPS_BEGIN(CedarOrdinaryFakeSharedExamples) using namespace Cedar::Matchers; using namespace Cedar::Doubles; using namespace Cedar::Doubles::Arguments; sharedExamplesFor(@"a Cedar ordinary fake", ^(NSDictionary *sharedContext) { __block id myOrdinaryFake; beforeEach(^{ myOrdinaryFake = [sharedContext objectForKey:@"double"]; }); context(@"of the correct types", ^{ NSNumber *arg1 = @1; NSNumber *arg2 = @2; NSNumber *arg3 = @3; context(@"with a specific argument value", ^{ context(@"when invoked with a parameter of non-matching value", ^{ beforeEach(^{ myOrdinaryFake stub_method("methodWithNumber1:andNumber2:").with(arg1, arg2).and_return(@3); }); it(@"should raise an exception", ^{ ^{ [myOrdinaryFake methodWithNumber1:arg1 andNumber2:arg3]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); }); context(@"with a nil argument", ^{ beforeEach(^{ myOrdinaryFake stub_method("methodWithNumber1:andNumber2:").with(nil, nil); }); context(@"when invoked with a non-nil argument", ^{ it(@"should raise an exception", ^{ ^{ [myOrdinaryFake methodWithNumber1:nil andNumber2:@123]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); }); context(@"with an argument specified as any instance of a specified class", ^{ NSNumber *arg = @123; beforeEach(^{ myOrdinaryFake stub_method("methodWithNumber1:andNumber2:").with(any([NSDecimalNumber class]), arg).and_return(@99); }); context(@"when invoked with the incorrect class", ^{ it(@"should raise an exception", ^{ ^{ [myOrdinaryFake methodWithNumber1:@3.14159265359 andNumber2:arg]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); context(@"when invoked with nil", ^{ it(@"should raise an exception", ^{ ^{ [myOrdinaryFake methodWithNumber1:nil andNumber2:arg]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); }); context(@"with an argument specified as any instance conforming to a specified protocol", ^{ NSNumber *arg = @123; beforeEach(^{ myOrdinaryFake stub_method("methodWithNumber1:andNumber2:").with(any(@protocol(InheritedProtocol)), arg).and_return(@99); }); context(@"when invoked with the incorrect class", ^{ it(@"should return 0", ^{ ^{ [myOrdinaryFake methodWithNumber1:@3.14159265359 andNumber2:arg]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); context(@"when invoked with nil", ^{ it(@"should return 0", ^{ ^{ [myOrdinaryFake methodWithNumber1:nil andNumber2:arg]; } should raise_exception.with_reason(@"Wrong arguments supplied to stub"); }); }); }); }); }); SHARED_EXAMPLE_GROUPS_END ================================================ FILE: Spec/Doubles/HaveReceivedSpec.mm ================================================ #import "Cedar.h" #import "SimpleIncrementer.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; using namespace Cedar::Doubles::Arguments; SPEC_BEGIN(HaveReceivedSpec) describe(@"have_received matcher", ^{ __block SimpleIncrementer *incrementer; beforeEach(^{ incrementer = [[[SimpleIncrementer alloc] init] autorelease]; spy_on(incrementer); }); context(@"with an actual value that is not a spy", ^{ beforeEach(^{ incrementer = [[[SimpleIncrementer alloc] init] autorelease]; }); it(@"should raise a descriptive exception", ^{ expectExceptionWithReason([NSString stringWithFormat:@"Received expectation for non-double object <%@>", incrementer], ^{ incrementer should have_received("increment"); }); }); }); context(@"with an object that is no longer being spied upon", ^{ beforeEach(^{ stop_spying_on(incrementer); }); it(@"should raise a descriptive exception", ^{ expectExceptionWithReason([NSString stringWithFormat:@"Received expectation for non-double object <%@>", incrementer], ^{ incrementer should have_received("increment"); }); }); }); context(@"for a method with no parameters", ^{ SEL method = @selector(increment); context(@"with a parameter expectation", ^{ it(@"should raise an exception due to an invalid expectation", ^{ NSString *methodString = NSStringFromSelector(method); NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for <%@>; expected: 1, actual: 0", methodString]; ^{ expect(incrementer).to(have_received(method).with(anything)); } should raise_exception.with_reason(reason); }); }); context(@"which has been called", ^{ beforeEach(^{ [incrementer increment]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method)); expect(incrementer).to(have_received("increment")); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received(method)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received("increment")); }); }); }); }); context(@"which has not been called", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to(have_received(method)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to(have_received("increment")); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method)); expect(incrementer).to_not(have_received("increment")); }); }); }); }); context(@"for a method with a non-object parameter", ^{ SEL method = @selector(incrementBy:); context(@"with too many parameter expectations", ^{ it(@"should raise an exception due to an invalid expectation", ^{ NSString *methodName = NSStringFromSelector(method); NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for <%@>; expected: 2, actual: 1", methodName]; ^{ expect(incrementer).to(have_received(method).with(anything, anything)); } should raise_exception.with_reason(reason); }); }); context(@"with too few parameter expectations", ^{ it(@"should raise an exception due to an invalid expectation", ^{ NSString *methodName = NSStringFromSelector(@selector(incrementByABit:andABitMore:)); NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for <%@>; expected: 1, actual: 2", methodName]; ^{ expect(incrementer).to(have_received(@selector(incrementByABit:andABitMore:)).with(anything)); } should raise_exception.with_reason(reason); }); }); context(@"which has been called", ^{ int actualParameter = 2; beforeEach(^{ [incrementer incrementBy:actualParameter]; }); context(@"with no parameter expectations", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method)); expect(incrementer).to(have_received("incrementBy:")); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received(method)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received("incrementBy:")); }); }); }); }); context(@"with the correct expected parameter", ^{ unsigned short expectedParameter = actualParameter; describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); expect(incrementer).to(have_received("incrementBy:").with(expectedParameter)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%d>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%d>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to_not(have_received("incrementBy:").with(expectedParameter)); }); }); }); }); context(@"with an incorrect expected parameter", ^{ unsigned short expectedParameter = actualParameter + 1; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%d> but received messages:\n" @" incrementBy:<2>\n" @" value\n" @" setValue:<2>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%d> but received messages:\n" @" incrementBy:<2>\n" @" value\n" @" setValue:<2>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received("incrementBy:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementBy:").with(expectedParameter)); }); }); }); }); context(@"which has not been called", ^{ long expectedParameter = 3; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%ld>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%ld>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received("incrementBy:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementBy:").with(expectedParameter)); }); }); }); }); context(@"for a method with an object parameter", ^{ SEL method = @selector(incrementByNumber:); id actualParameter = [NSNumber numberWithInt:3]; context(@"which has been called", ^{ beforeEach(^{ [incrementer incrementByNumber:actualParameter]; }); context(@"with no parameter expectations", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method)); expect(incrementer).to(have_received("incrementByNumber:")); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received(method)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to_not(have_received("incrementByNumber:")); }); }); }); }); context(@"with the correct expected parameter", ^{ NSNumber *expectedParameter = [NSNumber numberWithFloat:[actualParameter intValue]]; describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); expect(incrementer).to(have_received("incrementByNumber:").with(expectedParameter)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%@>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%@>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to_not(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); }); context(@"with an incorrect expected parameter", ^{ NSNumber *expectedParameter = [NSNumber numberWithFloat:[actualParameter floatValue] + 0.5]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<%@>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter, actualParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<%@>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter, actualParameter], ^{ expect(incrementer).to(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); context(@"with an incorrect expected parameter that is nil", ^{ context(@"that is typed as a number", ^{ NSNumber *expectedParameter = nil; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<3>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<3>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); context(@"that is typed as id", ^{ id expectedParameter = nil; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<3>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@> but received messages:\n" @" incrementByNumber:<3>\n" @" value\n" @" setValue:<3>\n", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); }); }); context(@"which has not been called", ^{ NSNumber *expectedParameter = [NSNumber numberWithInt:2]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received(method).with(expectedParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%@>", incrementer, NSStringFromSelector(method), expectedParameter], ^{ expect(incrementer).to(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedParameter)); expect(incrementer).to_not(have_received("incrementByNumber:").with(expectedParameter)); }); }); }); }); context(@"for a method with multiple parameters (some object, some not)", ^{ SEL method = @selector(incrementByABit:andABitMore:); int actualFirstParameter = 83; id actualSecondParameter = [NSNumber numberWithInt:32]; context(@"with too few parameter expectations", ^{ it(@"should raise an exception due to an invalid expectation", ^{ NSString *methodName = NSStringFromSelector(method); NSString *reason = [NSString stringWithFormat:@"Wrong number of expected parameters for <%@>; expected: 1, actual: 2", methodName]; ^{ expect(incrementer).to(have_received(method).with(anything)); } should raise_exception.with_reason(reason); }); }); context(@"which has been called", ^{ beforeEach(^{ [incrementer incrementByABit:actualFirstParameter andABitMore:actualSecondParameter]; }); context(@"with the correct expected parameter", ^{ int expectedFirstParameter = actualFirstParameter; NSObject * expectedSecondParameter = [NSNumber numberWithFloat:[actualSecondParameter floatValue]]; describe(@"positive match", ^{ it(@"should pass", ^{ expect(incrementer).to(have_received(method).with(expectedFirstParameter, expectedSecondParameter)); expect(incrementer).to(have_received("incrementByABit:andABitMore:").with(expectedFirstParameter, expectedSecondParameter)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%d, %@>", incrementer, NSStringFromSelector(method), expectedFirstParameter, expectedSecondParameter], ^{ expect(incrementer).to_not(have_received(method).with(expectedFirstParameter, expectedSecondParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not have received message <%@>, with arguments: <%d, %@>", incrementer, NSStringFromSelector(method), expectedFirstParameter, expectedSecondParameter], ^{ expect(incrementer).to_not(have_received("incrementByABit:andABitMore:").with(expectedFirstParameter, expectedSecondParameter)); }); }); }); }); context(@"with an incorrect parameter expectation", ^{ unsigned long long expectedFirstParameter = actualFirstParameter; NSObject * expectedSecondParameter = [NSNumber numberWithFloat:[actualSecondParameter floatValue] + 0.6]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%llu, %@> but received messages:\n" @" incrementByABit:andABitMore:<83, 32>\n" @" value\n" @" setValue:<115>\n", incrementer, NSStringFromSelector(method), expectedFirstParameter, expectedSecondParameter], ^{ expect(incrementer).to(have_received(method).with(expectedFirstParameter, expectedSecondParameter)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%llu, %@> but received messages:\n" @" incrementByABit:andABitMore:<83, 32>\n" @" value\n" @" setValue:<115>\n", incrementer, NSStringFromSelector(method), expectedFirstParameter, expectedSecondParameter], ^{ expect(incrementer).to(have_received("incrementByABit:andABitMore:").with(expectedFirstParameter, expectedSecondParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(expectedFirstParameter, expectedSecondParameter)); expect(incrementer).to_not(have_received("incrementByABit:andABitMore:").with(expectedFirstParameter, expectedSecondParameter)); }); }); }); }); context(@"which has been called with an incorrect nil parameter", ^{ NSObject * expectedSecondParameter = @666; beforeEach(^{ [incrementer incrementByABit:actualFirstParameter andABitMore:nil]; }); describe(@"positive match", ^{ it(@"should fail with a sensible error message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>, with arguments: <%d, 666> but received messages:\n" @" incrementByABit:andABitMore:<83, %@>\n" @" value\n" @" setValue:<83>\n", incrementer, NSStringFromSelector(method), actualFirstParameter, @""], ^{ expect(incrementer).to(have_received("incrementByABit:andABitMore:").with(actualFirstParameter, expectedSecondParameter)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method).with(0, nil)); expect(incrementer).to_not(have_received("incrementByABit:andABitMore:").with(actualFirstParameter, expectedSecondParameter)); }); }); }); context(@"which has not been called", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to(have_received(method)); }); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to have received message <%@>", incrementer, NSStringFromSelector(method)], ^{ expect(incrementer).to(have_received("incrementByABit:andABitMore:")); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(incrementer).to_not(have_received(method)); expect(incrementer).to_not(have_received("incrementByABit:andABitMore:")); }); }); }); }); context(@"for a method that the object does not respond to", ^{ SEL method = NSSelectorFromString(@"noSuchMethod:"); it(@"should raise an exception due to an invalid expectation", ^{ NSString *methodString = NSStringFromSelector(method); NSString *reason = [NSString stringWithFormat:@"Received expectation on method <%@>, which double <%@> does not respond to", methodString, incrementer]; ^{ expect(incrementer).to(have_received(method).with(anything)); } should raise_exception.with_reason(reason); }); }); context(@"for a method that throws an exception", ^{ it(@"should continue to record methods correctly", ^{ @try { [incrementer incrementWithException]; } @catch (NSException * ) { } [incrementer increment]; incrementer should have_received("increment"); }); }); }); SPEC_END ================================================ FILE: Spec/Focused/FocusedSpec.m ================================================ #import "Cedar.h" NSMutableArray *calledInFocusedSpec__ = nil; NSMutableArray *expectedCallsInFocusedSpec__ = nil; SPEC_BEGIN(FocusedSpec) calledInFocusedSpec__ = [[NSMutableArray alloc] init]; expectedCallsInFocusedSpec__ = [[NSMutableArray alloc] initWithObjects: @"fit", @"describe-fit", @"describe-describe-fit", @"describe-fdescribe-it", @"describe-fdescribe-fit", @"fdescribe-it", @"fdescribe-fit", @"fdescribe-describe-it", @"fdescribe-describe-fit", @"fdescribe-fdescribe-it", @"fdescribe-fdescribe-fit", @"context-fit", @"fcontext-it", @"fcontext-fit", nil]; it(@"should not run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"fit"]; }); describe(@"inside non-focused describe", ^{ it(@"should not run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-fit"]; }); describe(@"inside nested non-focused describe", ^{ it(@"should not run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-describe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-describe-fit"]; }); }); fdescribe(@"inside nested focused describe", ^{ it(@"should run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-fdescribe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"describe-fdescribe-fit"]; }); }); }); fdescribe(@"inside focused describe", ^{ it(@"should run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-fit"]; }); describe(@"inside nested non-focused describe", ^{ it(@"should run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-describe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-describe-fit"]; }); }); fdescribe(@"inside nested focused describe", ^{ it(@"should run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-fdescribe-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"fdescribe-fdescribe-fit"]; }); }); }); context(@"inside non-focused context", ^{ it(@"should not run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"context-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"context-fit"]; }); }); fcontext(@"inside focused context", ^{ it(@"should run non-focused example", ^{ [calledInFocusedSpec__ addObject:@"fcontext-it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec__ addObject:@"fcontext-fit"]; }); }); SPEC_END ================================================ FILE: Spec/Focused/FocusedSpec2.m ================================================ #import "Cedar.h" NSMutableArray *calledInFocusedSpec2__ = nil; NSMutableArray *expectedCallsInFocusedSpec2__ = nil; SPEC_BEGIN(FocusedSpec2) calledInFocusedSpec2__ = [[NSMutableArray alloc] init]; expectedCallsInFocusedSpec2__ = [[NSMutableArray alloc] initWithObjects:@"fit", nil]; it(@"should not run non-focused example", ^{ [calledInFocusedSpec2__ addObject:@"it"]; }); fit(@"should run focused example", ^{ [calledInFocusedSpec2__ addObject:@"fit"]; }); SPEC_END ================================================ FILE: Spec/Focused/main.mm ================================================ #import extern NSMutableArray *calledInFocusedSpec__; extern NSMutableArray *expectedCallsInFocusedSpec__; extern NSMutableArray *calledInFocusedSpec2__; extern NSMutableArray *expectedCallsInFocusedSpec2__; BOOL wereExpectedCallsMade(NSArray *actuallyCalled, NSArray *expectedCalls); int main (int argc, const char *argv[]) { CDRRunSpecs(); BOOL expectedCallsMade = wereExpectedCallsMade(calledInFocusedSpec__, expectedCallsInFocusedSpec__) && wereExpectedCallsMade(calledInFocusedSpec2__, expectedCallsInFocusedSpec2__); [calledInFocusedSpec__ release]; [expectedCallsInFocusedSpec__ release]; [calledInFocusedSpec2__ release]; [expectedCallsInFocusedSpec2__ release]; return expectedCallsMade ? 0 : 1; } BOOL wereExpectedCallsMade(NSArray *callsMade, NSArray *expectedCalls) { BOOL expectedCallsMade = YES; for (NSString *callName in expectedCalls) { if (![callsMade containsObject:callName]) { NSLog(@"Example '%@' was not ran but should have been.", callName); expectedCallsMade = NO; } } if ([callsMade count] > [expectedCalls count]) { NSLog(@"Extra examples were ran but should not have been."); expectedCallsMade = NO; } return expectedCallsMade; } ================================================ FILE: Spec/Matchers/Base/BeCloseToSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeCloseToSpec) describe(@"be_close_to matcher", ^{ describe(@"when the actual value and expected value are declared as NSDates", ^{ __block NSDate *expectedValue; NSDate *actualValue = [NSDate dateWithTimeIntervalSince1970:1]; describe(@"with an explicit threshold", ^{ NSTimeInterval threshold = 0.1; describe(@"and the values are within a given threshold", ^{ beforeEach(^{ expectedValue = [NSDate dateWithTimeIntervalSince1970:1.09]; }); describe(@"positive match", ^{ it(@"should pass", ^{ actualValue should be_close_to(expectedValue).within(threshold); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1970-01-01 00:00:01 +0000 (1.000000)> to not be close to <1970-01-01 00:00:01 +0000 (1.090000)> (within 0.1)", ^{ actualValue should_not be_close_to(expectedValue).within(threshold); }); }); }); }); context(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDate dateWithTimeIntervalSince1970:2]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1970-01-01 00:00:01 +0000 (1.000000)> to be close to <1970-01-01 00:00:02 +0000 (2.000000)> (within 0.1)", ^{ actualValue should be_close_to(expectedValue).within(threshold); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ actualValue should_not be_close_to(expectedValue).within(threshold); }); }); }); }); describe(@"without an explicit threshold", ^{ describe(@"and the values are within the default threshold", ^{ beforeEach(^{ expectedValue = [NSDate dateWithTimeIntervalSince1970:1.009]; }); describe(@"positive match", ^{ it(@"should pass", ^{ actualValue should be_close_to(expectedValue); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1970-01-01 00:00:01 +0000 (1.000000)> to not be close to <1970-01-01 00:00:01 +0000 (1.009000)> (within 0.01)", ^{ actualValue should_not be_close_to(expectedValue); }); }); }); }); context(@"and the values are not within the default threshold", ^{ beforeEach(^{ expectedValue = [NSDate dateWithTimeIntervalSince1970:2]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1970-01-01 00:00:01 +0000 (1.000000)> to be close to <1970-01-01 00:00:02 +0000 (2.000000)> (within 0.01)", ^{ actualValue should be_close_to(expectedValue); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ actualValue should_not be_close_to(expectedValue); }); }); }); }); }); describe(@"when the actual value is declared as a float", ^{ float actualValue = 2.0 / 3.0; describe(@"and the expected value is also a float", ^{ __block float expectedValue; describe(@"with an explicit threshold", ^{ float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = 2.0 / 3.0 + 0.01; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to not be close to <0.676667> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = 2.0 / 3.0 + 0.2; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to be close to <0.866667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"without an explicit threshold", ^{ describe(@"and the values are within the default threshold", ^{ beforeEach(^{ expectedValue = 2.0 / 3.0 + 0.000001; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to not be close to <0.666668> (within 0.01)", ^{ expect(actualValue).to_not(be_close_to(expectedValue)); }); }); }); }); describe(@"and the values are not within the default threshold", ^{ beforeEach(^{ expectedValue = 2.0 / 3.0 + 0.1; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to be close to <0.766667> (within 0.01)", ^{ expect(actualValue).to(be_close_to(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue)); }); }); }); }); }); describe(@"and the expected value is a compatible non-float type", ^{ __block int expectedValue; float threshold = 1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = 1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to not be close to <1> (within 1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = 5; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to be close to <5> (within 1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); }); describe(@"when the actual value is declared as an id", ^{ id actualValue = [NSNumber numberWithFloat:2.0 / 3.0 ]; describe(@"and the expected value is an id", ^{ __block id expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.1]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666667> to not be close to <0.7666667> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.2]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666667> to be close to <0.8666667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the expected value is an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0 + 0.1) decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666667> to not be close to <0.7666666666666666> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0 + 0.2) decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666667> to be close to <0.8666666666666667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ NSNumber *actualValue = [NSNumber numberWithFloat:2.0 / 3.0 ]; describe(@"and the expected value is an NSNumber *", ^{ __block NSNumber *expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.1]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to not be close to <0.766667> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.2]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to be close to <0.866667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the expected value is an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0 + 0.1) decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to not be close to <0.7666666666666666> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0 + 0.2) decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.666667> to be close to <0.8666666666666667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0) decimalValue]]; describe(@"and the expected value is an NSNumber *", ^{ __block NSNumber *expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ //We need to use a delta smaller than the threshold to account for non-decimals having less precision expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.09]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to not be close to <0.756667> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithFloat:2.0 / 3.0 + 0.2]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to be close to <0.866667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the expected value is an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ expectedValue = [[NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0) decimalValue]] decimalNumberByAdding:[NSDecimalNumber decimalNumberWithDecimal:[@(0.1) decimalValue]]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to not be close to <0.7666666666666666> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@(2.0 / 3.0 + 0.2) decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to be close to <0.8666666666666667> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@(2.0 / 3.0) decimalValue]; describe(@"and the expected value is an NSDecimal", ^{ __block NSDecimal expectedValue; float threshold = 0.1; describe(@"and the values are within the given threshold", ^{ beforeEach(^{ NSDecimal lhs = [@(2.0 / 3.0) decimalValue]; NSDecimal rhs = [@0.1 decimalValue]; NSDecimalAdd(&expectedValue, &lhs, &rhs, NSRoundPlain); }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to not be close to <0.7666666666666666> (within 0.1)", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); describe(@"and the values are not within the given threshold", ^{ beforeEach(^{ NSDecimal lhs = [@(2.0 / 3.0) decimalValue]; NSDecimal rhs = [@0.2 decimalValue]; NSDecimalAdd(&expectedValue, &lhs, &rhs, NSRoundPlain); }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <0.6666666666666666> to be close to <0.8666666666666666> (within 0.1)", ^{ expect(actualValue).to(be_close_to(expectedValue).within(threshold)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_close_to(expectedValue).within(threshold)); }); }); }); }); }); describe(@"when the actual value is not a valid type to compare", ^{ describe(@"positive match", ^{ it(@"should fail", ^{ expectFailureWithMessage(@"Actual value <1.0> (__NSCFConstantString) is not a numeric value (NSNumber, NSDate, float, etc.)", ^{ NSNumber *value = [@[@"1.0"] firstObject]; value should be_close_to(@1.0001); }); }); }); describe(@"negative match", ^{ it(@"should fail", ^{ expectFailureWithMessage(@"Actual value <1.0> (__NSCFConstantString) is not a numeric value (NSNumber, NSDate, float, etc.)", ^{ NSNumber *value = [@[@"1.0"] firstObject]; value should_not be_close_to(@1.0001); }); }); }); }); describe(@"when the expected value is nil", ^{ it(@"should alert the user that they probably did not mean to verify the value was close to nil", ^{ expectFailureWithMessage(@"Unexpected use of be_close_to matcher to check for nil; use the be_nil matcher to match nil values", ^{ NSNumber *value = @1.0f; NSNumber *expectedValue = nil; value should be_close_to(expectedValue); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeFalsySpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(BeFalsySpec) describe(@"be_falsy matcher", ^{ describe(@"when the value is a built-in type", ^{ __block BOOL value; describe(@"which evaluates to false", ^{ beforeEach(^{ value = NO; }); describe(@"positive match", ^{ it(@"should pass", ^{ value should be_falsy; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not evaluate to false", ^{ value should_not be_falsy; }); }); }); }); describe(@"which evaluates to true", ^{ beforeEach(^{ value = YES; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to evaluate to false", ^{ value should be_falsy; }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ value should_not be_falsy; }); }); }); }); describe(@"when the value is an id", ^{ __block id value; describe(@"which evaluates to false", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ value should be_falsy; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(null)> to not evaluate to false", ^{ value should_not be_falsy; }); }); }); }); describe(@"which evaluates to true", ^{ beforeEach(^{ value = @"cat"; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to evaluate to false", ^{ value should be_falsy; }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ value should_not be_falsy; }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeGTESpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeGTESpec) describe(@"be_gte matcher", ^{ int someInteger = 10; describe(@"when the actual value is a built-in type", ^{ int actualValue = someInteger; describe(@"and the expected value is the same built-in type", ^{ __block int expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = 1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = 100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is a different, but comparable, built-in type", ^{ __block float expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = 1.1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1.1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = 100.1; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100.1>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = someInteger / 1.0; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an id", ^{ id actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSObject *", ^{ NSObject *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSValue *", ^{ NSValue *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithString:@"10"]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ NSNumber *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@10 decimalValue]; describe(@"and the expected value is declared as an NSDecimal", ^{ __block NSDecimal expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [@1 decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [@100 decimalValue]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [@10 decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_gte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <10>", ^{ expect(actualValue).to_not(be_gte(expectedValue)); }); }); }); }); }); }); describe(@"When the expected value is nil", ^{ it(@"should alert the user that they probably did not mean to verify the value was >= nil", ^{ expectFailureWithMessage(@"Unexpected use of be_greater_than_or_equal_to matcher to check for nil; use the be_nil matcher to match nil values", ^{ NSNumber *value = @0.0f; NSNumber *expectedValue = nil; value should be_greater_than_or_equal_to(expectedValue); }); }); }); }); describe(@"be_greater_than_or_equal_to matcher", ^{ it(@"should have the same behavior as the be_gte matcher", ^{ expect(10).to(be_greater_than_or_equal_to(1)); expectFailureWithMessage(@"Expected <1> to be greater than or equal to <10>", ^{ expect(1).to(be_greater_than_or_equal_to(10)); }); }); }); //describe(@">= operator matcher", ^{ // describe(@"when the actual value is greater than the expected value", ^{ // it(@"should pass", ^{ // expect(10) >= 1; // }); // }); // // describe(@"when the actual value is less than the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be greater than or equal to <100>", ^{ // expect(10) >= 100; // }); // }); // }); // // describe(@"when the actual value equals the expected value", ^{ // it(@"should pass", ^{ // expect(10) >= 10; // }); // }); // // describe(@"with and without 'to'", ^{ // int actualValue = 10, expectedValue = 1; // // describe(@"positive match", ^{ // it(@"should pass", ^{ // expect(actualValue) >= expectedValue; // expect(actualValue).to >= expectedValue; // }); // }); // // describe(@"negative match", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to not be greater than or equal to <1>", ^{ // expect(actualValue).to_not >= expectedValue; // }); // }); // }); // }); //}); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeGreaterThanSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeGreaterThanSpec) describe(@"be_greater_than matcher", ^{ int someInteger = 10; describe(@"when the actual value is a built-in type", ^{ int actualValue = someInteger; describe(@"and the expected value is the same built-in type", ^{ __block int expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = 1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = 100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is a different, but comparable, built-in type", ^{ __block float expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = 1.1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = 100.1; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.1>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an id", ^{ id actualValue = @(someInteger); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.1>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSObject *", ^{ NSObject *actualValue = @(someInteger); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.1>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSValue *", ^{ NSValue *actualValue = @(someInteger); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.1>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ NSNumber *actualValue = @(someInteger); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = @1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = @100; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.1>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithDecimal:[@10.f decimalValue]]; describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@1.5f decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.5>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@100.5f decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.5>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@1.f decimalValue]];//[NSNumber numberWithInt:1]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@100.f decimalValue]];//[NSNumber numberWithInt:100]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@1.5f decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.5>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@100.5f decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.5>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@1 decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@100 decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@1 decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@100 decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [[actualValue copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@10.f decimalValue]; describe(@"and the expected value is declared as an NSDecimal", ^{ __block NSDecimal expectedValue; describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [@1.5f decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be greater than <1.5>", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [@100.5f decimalValue]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <100.5>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ expect(actualValue).to(be_greater_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_greater_than(expectedValue)); }); }); }); }); }); describe(@"when the expected value is nil", ^{ it(@"should alert the user that they probably did not mean to verify that the value was greater than nil", ^{ expectFailureWithMessage(@"Unexpected use of be_greater_than matcher to check for nil; use the be_nil matcher to match nil values", ^{ NSNumber *value = @1.0f; NSNumber *expectedValue = nil; value should be_greater_than(expectedValue); }); }); }); }); //describe(@"> operator matcher", ^{ // describe(@"when the actual value is greater than the expected value", ^{ // it(@"should pass", ^{ // expect(10) > 1; // }); // }); // // describe(@"when the actual value is less than the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be greater than <100>", ^{ // expect(10) > 100; // }); // }); // }); // // describe(@"when the actual value equals the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be greater than <10>", ^{ // expect(10) > 10; // }); // }); // }); // // describe(@"with and without 'to'", ^{ // int actualValue = 10, expectedValue = 1; // // describe(@"positive match", ^{ // it(@"should pass", ^{ // expect(actualValue) > expectedValue; // expect(actualValue).to > expectedValue; // }); // }); // // describe(@"negative match", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to not be greater than <1>", ^{ // expect(actualValue).to_not > expectedValue; // }); // }); // }); // }); //}); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeInstanceOfSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" @interface FooBase : NSObject; @end @implementation FooBase; @end @interface FooDerived : FooBase; @end @implementation FooDerived; @end @interface BarNotMemberOfOwnClass : NSObject @end @implementation BarNotMemberOfOwnClass - (BOOL)isMemberOfClass:(Class)aClass { return NO; } - (BOOL)isKindOfClass:(Class)aClass { return NO; } @end using namespace Cedar::Matchers; SPEC_BEGIN(BeInstanceOfSpec) describe(@"be_instance_of matcher", ^{ describe(@"without decoration", ^{ Class expectedClass = [FooBase class]; describe(@"when the actual value is an instance of the expected class", ^{ id actualValue = [[[FooBase alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(actualValue).to(be_instance_of(expectedClass)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to not be an instance of class <%@>", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to_not(be_instance_of(expectedClass)); }); }); }); }); describe(@"when the actual value is an instance of a subclass of the expected class", ^{ id actualValue = [[[FooDerived alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to be an instance of class <%@>", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to(be_instance_of(expectedClass)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(actualValue).to_not(be_instance_of(expectedClass)); }); }); }); describe(@"when the actual value is not an instance of the expected class, or any of its subclasses", ^{ id actualValue = [NSString string]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to be an instance of class <%@>", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to(be_instance_of(expectedClass)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(actualValue).to_not(be_instance_of(expectedClass)); }); }); }); describe(@"when the actual value is not an instance of the expected class but they have the same class name", ^{ Class expectedClass = [BarNotMemberOfOwnClass class]; id actualValue = [[[BarNotMemberOfOwnClass alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should fail with a failure message suggesting solution to the problem", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to be an instance of class <%@>. Did you accidentally add the class to your specs target also?", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to(be_instance_of(expectedClass)); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(actualValue).to_not(be_instance_of(expectedClass)); }); }); }); }); describe(@"with the or_any_subclass decoration", ^{ Class expectedClass = [FooBase class]; describe(@"when the actual value is an instance of the expected class", ^{ id actualValue = [[[FooBase alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(actualValue).to(be_instance_of(expectedClass).or_any_subclass()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to not be an instance of class <%@>, or any of its subclasses", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to_not(be_instance_of(expectedClass).or_any_subclass()); }); }); }); }); describe(@"when the actual value is an instance of a subclass of the expected class", ^{ id actualValue = [[[FooDerived alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(actualValue).to(be_instance_of(expectedClass).or_any_subclass()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to not be an instance of class <%@>, or any of its subclasses", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to_not(be_instance_of(expectedClass).or_any_subclass()); }); }); }); }); describe(@"when the actual value is not an instance of the expected class, or any of its subclasses", ^{ id actualValue = [NSString string]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to be an instance of class <%@>, or any of its subclasses", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to(be_instance_of(expectedClass).or_any_subclass()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(actualValue).to_not(be_instance_of(expectedClass).or_any_subclass()); }); }); }); describe(@"when the actual value is not an instance of the expected class but they have the same class name", ^{ Class expectedClass = [BarNotMemberOfOwnClass class]; id actualValue = [[[BarNotMemberOfOwnClass alloc] init] autorelease]; describe(@"positive match", ^{ it(@"should fail with a failure message suggesting solution to the problem", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@ (%@)> to be an instance of class <%@>, or any of its subclasses. Did you accidentally add the class to your specs target also?", actualValue, [actualValue class], expectedClass], ^{ expect(actualValue).to(be_instance_of(expectedClass).or_any_subclass()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(actualValue).to_not(be_instance_of(expectedClass).or_any_subclass()); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeLTESpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeLTESpec) describe(@"be_lte matcher", ^{ int someInteger = 10; describe(@"when the actual value is a built-in type", ^{ int actualValue = someInteger; describe(@"and the expected value is the same built-in type", ^{ __block int expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 10; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = someInteger / 10; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = someInteger; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is a different, but comparable, built-in type", ^{ __block float expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 10.0; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = someInteger / 10.0; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 1.0; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an id", ^{ id actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSObject *", ^{ NSObject *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSValue *", ^{ NSValue *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ NSNumber *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithString:@"10"]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@10 decimalValue]; describe(@"and the expected value is declared as an NSDecimal", ^{ __block NSDecimal expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [@100 decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <100>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [@1 decimalValue]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [@10 decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_lte(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than or equal to <10>", ^{ expect(actualValue).to_not(be_lte(expectedValue)); }); }); }); }); }); }); describe(@"when the expected value is nil", ^{ it(@"should alert the user that they probably did not mean to verify the value was less than or equal to nil", ^{ expectFailureWithMessage(@"Unexpected use of be_less_than_or_equal_to matcher to check for nil; use the be_nil matcher to match nil values", ^{ NSNumber *value = @1.0f; NSNumber *expectedValue = nil; value should be_less_than_or_equal_to(expectedValue); }); }); }); }); describe(@"be_less_than_or_equal_to matcher", ^{ it(@"should have the same behavior as the be_lte matcher", ^{ expect(1).to(be_less_than_or_equal_to(10)); expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ expect(10).to(be_less_than_or_equal_to(1)); }); }); }); //describe(@"<= operator matcher", ^{ // describe(@"when the actual value is less than the expected value", ^{ // it(@"should pass", ^{ // expect(1) <= 10; // }); // }); // // describe(@"when the actual value is greater than the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be less than or equal to <1>", ^{ // expect(10) <= 1; // }); // }); // }); // // describe(@"when the actual value equals the expected value", ^{ // it(@"should pass", ^{ // expect(10) <= 10; // }); // }); // // describe(@"with and without 'to'", ^{ // int actualValue = 1, expectedValue = 10; // // describe(@"positive match", ^{ // it(@"should pass", ^{ // expect(actualValue) <= expectedValue; // expect(actualValue).to <= expectedValue; // }); // }); // // describe(@"negative match", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <1> to not be less than or equal to <10>", ^{ // expect(actualValue).to_not <= expectedValue; // }); // }); // }); // }); //}); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeLessThanSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeLessThanSpec) describe(@"be_less_than matcher", ^{ int someInteger = 10; describe(@"when the actual value is a built-in type", ^{ int actualValue = someInteger; describe(@"and the expected value is the same built-in type", ^{ __block int expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 10; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = someInteger / 10; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is a different, but comparable, built-in type", ^{ __block float expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 10.0; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = someInteger / 10.0; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = someInteger * 1.0; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an id", ^{ id actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.1>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSObject *", ^{ NSObject *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.1>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSValue *", ^{ NSValue *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.1>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ NSNumber *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.1>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithDecimal:[@(someInteger) decimalValue]]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger * 10]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger / 10]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"100.1"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.1>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.1>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"10"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@10.f decimalValue]; describe(@"and the expected value is declared as an NSDecimal", ^{ __block NSDecimal expectedValue; describe(@"and the actual value is less than the expected value", ^{ beforeEach(^{ expectedValue = [@100.5f decimalValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to not be less than <100.5>", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); describe(@"and the actual value is greater than the expected value", ^{ beforeEach(^{ expectedValue = [@1.5f decimalValue]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <1.5>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); describe(@"and the actual value equals the expected value", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ expect(actualValue).to(be_less_than(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_less_than(expectedValue)); }); }); }); }); }); describe(@"when the expected value is nill", ^{ it(@"should alert the user that the probaby did not mean to verify the value was less than nill", ^{ expectFailureWithMessage(@"Unexpected use of be_less_than matcher to check for nil; use the be_nil matcher to match nil values", ^{ NSNumber * value = @1.0f; NSNumber * expectedValue = nil; value should be_less_than(expectedValue); }); }); }); }); //describe(@"< operator matcher", ^{ // describe(@"when the actual value is less than the expected value", ^{ // it(@"should pass", ^{ // expect(1) < 10; // }); // }); // // describe(@"when the actual value is greater than the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be less than <1>", ^{ // expect(10) < 1; // }); // }); // }); // // describe(@"when the actual value equals the expected value", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <10> to be less than <10>", ^{ // expect(10) < 10; // }); // }); // }); // // describe(@"with and without 'to'", ^{ // int actualValue = 1, expectedValue = 10; // // describe(@"positive match", ^{ // it(@"should pass", ^{ // expect(actualValue) < expectedValue; // expect(actualValue).to < expectedValue; // }); // }); // // describe(@"negative match", ^{ // it(@"should fail with a sensible failure message", ^{ // expectFailureWithMessage(@"Expected <1> to not be less than <10>", ^{ // expect(actualValue).to_not < expectedValue; // }); // }); // }); // }); //}); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeNilSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeNilSpec) describe(@"be_nil matcher", ^{ describe(@"when the value is a pointer to a built-in type", ^{ __block int * value; describe(@"which is NULL", ^{ beforeEach(^{ value = NULL; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not NULL", ^{ __block int i = 7; beforeEach(^{ value = &i; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is an id", ^{ __block id value; describe(@"which is nil", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not nil", ^{ beforeEach(^{ value = [NSString string]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is a block", ^{ __block void(^value)(void); describe(@"which is nil", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not nil", ^{ beforeEach(^{ value = ^{}; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is not a pointer", ^{ int value = 7; it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Attempt to compare non-pointer type to nil"], ^{ expect(value).to(be_nil()); }); }); }); }); describe(@"be_nil shorthand syntax (no parentheses)", ^{ void *value = NULL; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeNil_ARCSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeNil_ARCSpec) describe(@"be_nil matcher (under ARC)", ^{ describe(@"when the value is a pointer to a built-in type", ^{ __block int * value; describe(@"which is NULL", ^{ beforeEach(^{ value = NULL; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not NULL", ^{ __block int i = 7; beforeEach(^{ value = &i; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is an id (__weak)", ^{ __block id sValue; __weak __block id value; describe(@"which is nil", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not nil", ^{ beforeEach(^{ value = sValue = [NSString string]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is an id (__strong)", ^{ __block id value; describe(@"which is nil", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not nil", ^{ beforeEach(^{ value = [NSString string]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is a block", ^{ __block void(^value)(void); describe(@"which is nil", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"which is not nil", ^{ beforeEach(^{ value = ^{}; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be nil", value], ^{ expect(value).to(be_nil()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_nil()); }); }); }); }); describe(@"when the value is not a pointer", ^{ int value = 7; it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Attempt to compare non-pointer type to nil"], ^{ expect(value).to(be_nil()); }); }); }); }); describe(@"be_nil shorthand syntax (no parentheses)", ^{ void *value = NULL; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_nil); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not be nil", ^{ expect(value).to_not(be_nil); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeSameInstanceAsSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeSameInstanceAsSpec) describe(@"be_same_instance_as matcher", ^{ describe(@"when the actual value is not a pointer", ^{ int actualValue = 1; int *expectedValue = nil; it(@"should fail with an exception", ^{ expectFailureWithMessage(@"Attempt to compare non-pointer type for sameness.", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"when the actual value is a pointer", ^{ int i = 17; int *actualValue = &i; describe(@"and the values point to the same address space", ^{ int *expectedValue = actualValue; describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space", ^{ int *expectedValue = nil; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"when the actual value is nil", ^{ int *actualValue = nil; describe(@"and the values are both nil", ^{ int *expectedValue = nil; it(@"should not pass", ^{ expectFailureWithMessage(@"Unexpected use of be_same_instance_as matcher to check for nil. Both the actual and given values are nil. This is probably not what you intended to verify.", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeSameInstanceAs_ARCSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeSameInstanceAs_ARCSpec) describe(@"be_same_instance_as matcher (under ARC)", ^{ describe(@"when the actual value is not a pointer", ^{ int actualValue = 1; int *expectedValue = nil; it(@"should fail with an exception", ^{ expectFailureWithMessage(@"Attempt to compare non-pointer type for sameness.", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"when the actual value is a pointer", ^{ int i = 17; int *actualValue = &i; describe(@"and the values point to the same address space", ^{ int *expectedValue = actualValue; describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space", ^{ int *expectedValue = nil; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"when the actual value is an id (__strong)", ^{ __block id actualValue; beforeEach(^{ actualValue = [[NSObject alloc] init]; }); describe(@"and the values point to the same address space (__strong)", ^{ __block id expectedValue; beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space (__strong)", ^{ __block id expectedValue; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); describe(@"and the values point to the same address space (__weak)", ^{ __weak __block id expectedValue; beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space (__weak)", ^{ __weak id expectedValue = nil; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"when the actual value is an id (__weak)", ^{ __block id strongActualValue; __weak __block id actualValue; beforeEach(^{ strongActualValue = [[NSString alloc] init]; actualValue = strongActualValue; }); describe(@"and the values point to the same address space (__strong)", ^{ __block id expectedValue; beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space (__strong)", ^{ __block id expectedValue; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); describe(@"and the values point to the same address space (__weak)", ^{ __weak __block id expectedValue; beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to not be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); describe(@"and the values do not point to the same address space (__weak)", ^{ __weak __block id expectedValue; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%p> to be same instance as <%p>", actualValue, expectedValue], ^{ expect(actualValue).to(be_same_instance_as(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(be_same_instance_as(expectedValue)); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BeTruthySpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeTruthySpec) describe(@"be_truthy matcher", ^{ describe(@"when the value is a built-in type", ^{ __block BOOL value; describe(@"which evaluates to true", ^{ beforeEach(^{ value = YES; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_truthy()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not evaluate to true", ^{ expect(value).to_not(be_truthy()); }); }); }); }); describe(@"which evaluates to false", ^{ beforeEach(^{ value = NO; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to evaluate to true", ^{ expect(value).to(be_truthy()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_truthy()); }); }); }); }); describe(@"when the value is an id", ^{ __block id value; describe(@"which evaluates to true", ^{ beforeEach(^{ value = @"wibble"; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_truthy()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not evaluate to true", ^{ expect(value).to_not(be_truthy()); }); }); }); }); describe(@"which evaluates to false", ^{ beforeEach(^{ value = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(null)> to evaluate to true", ^{ expect(value).to(be_truthy()); }); }); }); describe(@"negative match", ^{ it(@"should should pass", ^{ expect(value).to_not(be_truthy()); }); }); }); }); }); describe(@"be_truthy shorthand syntax (no parentheses)", ^{ BOOL value = YES; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(value).to(be_truthy); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not evaluate to true", ^{ expect(value).to_not(be_truthy); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BlockMatcherSpec.mm ================================================ #import #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BlockMatcherSpec) describe(@"BlockMatcher", ^{ context(@"when the matcher is typed as 'id'", ^{ id expectedSubject = @"subj"; context(@"and the subject is typed as 'id'", ^{ __block id actualSubject; context(@"when no failure message is provided", ^{ auto be_a_match = expectationVerifier(^(id subject){ return [subject isEqual:expectedSubject]; }).matcher(); describe(@"positive match", ^{ it(@"should pass", ^{ actualSubject = @"subj"; actualSubject should be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"other"; expectFailureWithMessage(@"Expected to pass a test", ^{ actualSubject should be_a_match; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ actualSubject = @"other"; actualSubject should_not be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"subj"; expectFailureWithMessage(@"Expected to not pass a test", ^{ actualSubject should_not be_a_match; }); }); }); }); context(@"when a failure message string is provided", ^{ CedarBlockMatcher be_a_match = expectationVerifier(^(id subject){ return [subject isEqual:expectedSubject]; }).with_failure_message_end(@"be a match").matcher(); describe(@"positive match", ^{ it(@"should pass", ^{ actualSubject = @"subj"; actualSubject should be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"other"; expectFailureWithMessage(@"Expected to be a match", ^{ actualSubject should be_a_match; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ actualSubject = @"other"; actualSubject should_not be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"subj"; expectFailureWithMessage(@"Expected to not be a match", ^{ actualSubject should_not be_a_match; }); }); }); }); context(@"when a failure message block is provided", ^{ auto be_a_match = expectationVerifier(^(id subject){ return [subject isEqual:expectedSubject]; }).with_failure_message_end(^{ return @"be a perfect match"; }).matcher(); describe(@"positive match", ^{ it(@"should pass", ^{ actualSubject = @"subj"; actualSubject should be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"other"; expectFailureWithMessage(@"Expected to be a perfect match", ^{ actualSubject should be_a_match; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ actualSubject = @"other"; actualSubject should_not be_a_match; }); it(@"should fail with the returned failure message", ^{ actualSubject = @"subj"; expectFailureWithMessage(@"Expected to not be a perfect match", ^{ actualSubject should_not be_a_match; }); }); }); }); }); context(@"and the subject is typed as an object subclass", ^{ auto be_a_match = expectationVerifier(^(id subject){ return [subject isEqual:expectedSubject]; }).matcher(); __block NSString *actualSubject; it(@"should pass", ^{ actualSubject = @"subj"; actualSubject should be_a_match; }); }); }); context(@"when the matcher is typed as an object subclass", ^{ NSString *expectedSubject = @"subj"; auto be_a_match = expectationVerifier(^(NSString *subject){ return [subject isEqual:expectedSubject]; }).matcher(); context(@"and the subject has the same type", ^{ it(@"should pass", ^{ NSString *actualSubject = @"subj"; actualSubject should be_a_match; }); }); context(@"and the subject is a subclass of the matcher's type", ^{ it(@"should pass", ^{ NSMutableString *actualSubject = [@"subj" mutableCopy]; actualSubject should be_a_match; }); }); }); context(@"when the subject is a primitive", ^{ NSInteger expectedSubject = 42; auto be_a_match = expectationVerifier(^(NSInteger subject){ return subject == expectedSubject; }).matcher(); describe(@"positive match", ^{ it(@"should pass", ^{ 42 should be_a_match; }); it(@"should fail with the returned failure message", ^{ expectFailureWithMessage(@"Expected <999> to pass a test", ^{ 999 should be_a_match; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ 999 should_not be_a_match; }); it(@"should fail with the returned failure message", ^{ expectFailureWithMessage(@"Expected <42> to not pass a test", ^{ 42 should_not be_a_match; }); }); }); }); describe(@"builder shorthand", ^{ it(@"should allow building a matcher via implicit conversion", ^{ CedarBlockMatcher pass = expectationVerifier(^(id subject){ return true; }); @"hi" should pass; }); it(@"should allow building a matcher including failure_message_end with a single function call", ^{ auto be_cute = matcherFor(@"be cute", ^(NSString *subject){ return [[subject lowercaseString] rangeOfString:@"kitten"].location != NSNotFound; }); @"kittens" should be_cute; expectFailureWithMessage(@"Expected to be cute", ^{ @"snakes" should be_cute; }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/BlockMatcher_ARCSpecSpec.mm ================================================ #import using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(BlockMatcher_ARCSpecSpec) describe(@"BlockMatcher", ^{ id expectedSubject = @"subj"; auto be_a_match = expectationVerifier(^(id subject){ return [subject isEqual:expectedSubject]; }).matcher(); it(@"should be usable under ARC", ^{ @"subj" should be_a_match; }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/ConformToSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" @protocol INonConformer @end @protocol IConformer @end @interface Conformer : NSObject @end @implementation Conformer @end using namespace Cedar::Matchers; SPEC_BEGIN(ConformToSpec) describe(@"conform_to matcher", ^{ context(@"when called on class", ^{ __block Class subject = Nil; beforeEach(^{ subject = [Conformer class]; }); afterEach(^{ subject = Nil; }); describe(@"positive match", ^{ it(@"should pass with protocol", ^{ subject should conform_to(@protocol(IConformer)); }); it(@"should pass with string", ^{ subject should conform_to("IConformer"); }); it(@"should fail with a sensible failure message", ^{ const char *protocolName = "INonConformer"; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to conform to <%s> protocol", subject, protocolName], ^{ subject should conform_to(protocolName); }); }); }); describe(@"negative match", ^{ it(@"should pass with protocol", ^{ subject should_not conform_to(@protocol(INonConformer)); }); it(@"should pass with string", ^{ subject should_not conform_to("INonConformer"); }); it(@"should fail with a sensible failure message", ^{ Protocol *protocol = @protocol(IConformer); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not conform to <%@> protocol", subject, NSStringFromProtocol(protocol)], ^{ subject should_not conform_to(protocol); }); }); }); }); context(@"when called on instance", ^{ __block Conformer *subject = nil; beforeEach(^{ subject = [[[Conformer alloc] init] autorelease]; }); afterEach(^{ subject = nil; }); describe(@"positive match", ^{ it(@"should pass with protocol", ^{ subject should conform_to(@protocol(IConformer)); }); it(@"should pass with string", ^{ subject should conform_to("IConformer"); }); it(@"should fail with a sensible failure message", ^{ Protocol *protocol = @protocol(INonConformer); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to conform to <%@> protocol", subject, NSStringFromProtocol(protocol)], ^{ subject should conform_to(protocol); }); }); }); describe(@"negative match", ^{ it(@"should pass with protocol", ^{ subject should_not conform_to(@protocol(INonConformer)); }); it(@"should pass with string", ^{ subject should_not conform_to("INonConformer"); }); it(@"should fail with a sensible failure message", ^{ Protocol *protocol = @protocol(IConformer); expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not conform to <%@> protocol", subject, NSStringFromProtocol(protocol)], ^{ subject should_not conform_to(protocol); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/EqualSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" #ifndef NS_ROOT_CLASS #define NS_ROOT_CLASS #endif using namespace Cedar::Matchers; @interface CustomObject : NSObject { BOOL shouldEqual_; } @property (nonatomic, assign) BOOL shouldEqual; @end @implementation CustomObject @synthesize shouldEqual = shouldEqual_; - (BOOL)isEqual:(id)object { return self.shouldEqual; } - (NSString *)description { return @"CustomObject"; } @end #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-root-class" NS_ROOT_CLASS @interface ClassWithoutDescriptionMethod #pragma clang diagnostic pop @end @implementation ClassWithoutDescriptionMethod + (id)alloc { return NSAllocateObject(self, 0, NULL); } - (void)dealloc { NSDeallocateObject(self); } - (id)init { return self; } - (BOOL)isEqual:(id)other { return NO; } @end SPEC_BEGIN(EqualSpec) describe(@"equal matcher", ^{ describe(@"when the actual value is a built-in type", ^{ int actualValue = 1; describe(@"and the expected value is the same built-in type", ^{ __block int expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = 1; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to not equal <1>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = 147; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to equal <147>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is a different, but comparable, built-in type", ^{ __block float expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = 1.0; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to not equal <1>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = 0.87; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to equal <0.87>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is a char type", ^{ char actualValue = 1; it(@"should properly display any failure message", ^{ expectFailureWithMessage(@"Expected <1> to equal <63>", ^{ char expectedValue = 63; expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"when the actual value is an id type that doesn't respond to -description", ^{ __block id actualValue; beforeEach(^{ actualValue = [[ClassWithoutDescriptionMethod alloc] init]; }); afterEach(^{ [actualValue dealloc]; }); it(@"should properly display any failure message", ^{ ^{ [NSString stringWithFormat:@"%p", actualValue]; }(); expectFailureWithMessage([NSString stringWithFormat:@"Expected to equal ", actualValue], ^{ actualValue should equal(@"doesntmatter"); }); }); }); describe(@"when the actual value is declared as an id", ^{ int someInteger = 7; id actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); describe(@"and the values are nil", ^{ id actualValue = nil; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); }); }); describe(@"and the expected value is also declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); describe(@"and the values are nil", ^{ id actualValue = nil; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"7.0"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <1.1>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSObject *", ^{ int someInteger = 7; NSObject *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is also declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); describe(@"and the values are nil", ^{ NSObject *actualValue = nil; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); describe(@"and the values are nil", ^{ NSObject *actualValue = nil; beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); }); }); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"7.0"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <1.1>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as a C string", ^{ char *actualValue = (char *)"value"; describe(@"and the expected value is declared as a C string", ^{ __block char *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = (char *)calloc(strlen(actualValue) + 1, sizeof(char)); stpcpy(expectedValue, actualValue); }); afterEach(^{ free(expectedValue); }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not equal ", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = (char *)calloc(strlen(actualValue) + 1, sizeof(char)); stpcpy(expectedValue, "eulav"); }); afterEach(^{ free(expectedValue); }); describe(@"positive match", ^{ it(@"should pass", ^{ expectFailureWithMessage(@"Expected to equal ", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as a const C string", ^{ __block const char *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = "value"; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not equal ", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); }); describe(@"when the actual value is declared as char array", ^{ // char[] cannot be copied through blocks describe(@"and the expected value is declared as a C string", ^{ __block char *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = (char *)"value"; }); describe(@"positive match", ^{ it(@"should pass", ^{ char actualValue[] = "value"; expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not equal ", ^{ char actualValue[] = "value"; expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = (char *)"eulav"; }); describe(@"positive match", ^{ it(@"should pass", ^{ expectFailureWithMessage(@"Expected to equal ", ^{ char actualValue[] = "value"; expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ char actualValue[] = "value"; expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSString *", ^{ int someInteger = 7; NSString *actualValue = [[NSString alloc] initWithFormat:@"%d", someInteger]; describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [[actualValue mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSString stringWithFormat:@"%d", someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [[actualValue mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSString stringWithFormat:@"%d", someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is also declared as an NSString *", ^{ __block NSString *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [[actualValue mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSString stringWithFormat:@"%d", someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSValue *", ^{ int someInteger = 7; NSValue *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is also declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:someInteger + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"7.0"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <1.1>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSNumber *", ^{ int someInteger = 7; NSNumber *actualValue = [NSNumber numberWithInt:someInteger]; describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); describe(@"and the expected value is nil", ^{ beforeEach(^{ expectedValue = nil; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Unexpected use of equal matcher to check for nil; use the be_nil matcher to match nil values", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible (for NSValue objects) failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible (for NSValue objects) failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSDecimalNumber", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"7.0"]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithString:@"1.1"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <1.1>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimalNumber *", ^{ NSDecimalNumber *actualValue = [NSDecimalNumber decimalNumberWithDecimal:[@7.f decimalValue]]; describe(@"and the expected value is declared as an NSDecimalNumber *", ^{ __block NSDecimalNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[actualValue decimalValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSDecimalNumber decimalNumberWithDecimal:[@8 decimalValue]]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSNumber *", ^{ __block NSNumber *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an NSValue *", ^{ __block NSValue *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible (for NSValue objects) failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible (for NSValue objects) failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue]]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSNumber numberWithInt:[actualValue intValue] + 1]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSDecimal", ^{ NSDecimal actualValue = [@7.f decimalValue]; describe(@"and the expected value is declared as an NSDecimal", ^{ __block NSDecimal expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = actualValue; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to not equal <7>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [@8 decimalValue]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <7> to equal <8>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is declared as an NSArray *", ^{ NSString *arrayContents = @"Hello"; NSArray *actualArray = [NSArray arrayWithObject:arrayContents]; describe(@"and the expected value is declared as an NSObject *", ^{ __block NSObject *expectedArray; describe(@"and the values are equal", ^{ beforeEach(^{ expectedArray = [[actualArray mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualArray).to(equal(expectedArray)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to not equal <(\n Hello\n)>", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedArray = [NSArray arrayWithObject:@"goodbye"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to equal <(\n goodbye\n)>", ^{ expect(actualArray).to(equal(expectedArray)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the expected value is declared as an id", ^{ __block id expectedArray; describe(@"and the values are equal", ^{ beforeEach(^{ expectedArray = [[actualArray mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualArray).to(equal(expectedArray)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to not equal <(\n Hello\n)>", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedArray = [NSArray arrayWithObject:@"goodbye"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to equal <(\n goodbye\n)>", ^{ expect(actualArray).to(equal(expectedArray)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the expected value is declared as an NSArray *", ^{ __block NSArray *expectedArray; describe(@"and the values are equal", ^{ beforeEach(^{ expectedArray = [[actualArray mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualArray).to(equal(expectedArray)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to not equal <(\n Hello\n)>", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedArray = [NSArray arrayWithObject:@"goodbye"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to equal <(\n goodbye\n)>", ^{ expect(actualArray).to(equal(expectedArray)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the expected value is declared as an NSMutableArray *", ^{ __block NSMutableArray *expectedArray; describe(@"and the values are equal", ^{ beforeEach(^{ expectedArray = [[actualArray mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualArray).to(equal(expectedArray)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to not equal <(\n Hello\n)>", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedArray = [[@[@"goodbye"] mutableCopy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n Hello\n)> to equal <(\n goodbye\n)>", ^{ expect(actualArray).to(equal(expectedArray)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualArray).to_not(equal(expectedArray)); }); }); }); }); }); describe(@"when the actual value is declared as an NSRange", ^{ NSRange actualValue = NSMakeRange(42, 56); describe(@"and the expected value is declared as an NSRange", ^{ __block NSRange expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = NSMakeRange(42, 56); }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{42, 56}> to not equal <{42, 56}>", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the locations are not equal", ^{ beforeEach(^{ expectedValue = NSMakeRange(0, 56); }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{42, 56}> to equal <{0, 56}>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); describe(@"and the lengths are not equal", ^{ beforeEach(^{ expectedValue = NSMakeRange(42, 0); }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{42, 56}> to equal <{42, 0}>", ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"custom objects (user-defined)", ^{ describe(@"with an actual value declared as CustomObject *", ^{ __block CustomObject *actualObject; beforeEach(^{ actualObject = [[[CustomObject alloc] init] autorelease]; }); describe(@"and the expected value declared as CustomObject *", ^{ __block CustomObject *expectedObject; describe(@"and the values are equal", ^{ beforeEach(^{ actualObject.shouldEqual = YES; expectedObject = [[[CustomObject alloc] init] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualObject).to(equal(expectedObject)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not equal ", ^{ expect(actualObject).to_not(equal(expectedObject)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ actualObject.shouldEqual = NO; expectedObject = [[[CustomObject alloc] init] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to equal ", ^{ expect(actualObject).to(equal(expectedObject)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualObject).to_not(equal(expectedObject)); }); }); }); }); }); }); }); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-comparison" describe(@"== operator matcher", ^{ describe(@"when the actual value is equal to the expected value", ^{ it(@"should pass", ^{ expect(1) == 1; }); }); describe(@"when the actual value is not equal to the expected value", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to equal <10>", ^{ expect(1) == 10; }); }); }); describe(@"with and without 'to'", ^{ int actualValue = 1, expectedValue = 1; describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue) == expectedValue; expect(actualValue).to == expectedValue; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to not equal <1>", ^{ expect(actualValue).to_not == expectedValue; }); }); }); }); }); describe(@"!= operator matcher", ^{ describe(@"when the actual value is equal to the expected value", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <1> to not equal <1>", ^{ expect(1) != 1; }); }); }); describe(@"when the actual value is not equal to the expected value", ^{ it(@"should pass", ^{ expect(1) != 10; }); }); describe(@"with and without 'to'", ^{ int actualValue = 1, expectedValue = 10; describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue) != expectedValue; expect(actualValue).to != expectedValue; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message (despite the double negative)", ^{ expectFailureWithMessage(@"Expected <1> to equal <10>", ^{ expect(actualValue).to_not != expectedValue; }); }); }); }); }); #pragma clang diagnostic pop SPEC_END ================================================ FILE: Spec/Matchers/Base/ExistSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(ExistSpec) NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *cacheURL = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] objectAtIndex:0]; describe(@"exist matcher", ^{ if (![fileManager fileExistsAtPath:cacheURL.path]) { [fileManager createDirectoryAtPath:cacheURL.path withIntermediateDirectories:YES attributes:@{} error:NULL] should be_truthy; } describe(@"when the actual value is an NSURL *", ^{ __block NSURL *URL; context(@"pointing to a resource that exists on the filesystem", ^{ beforeEach(^{ URL = [cacheURL URLByAppendingPathComponent:@"data.file"]; [URL isFileURL] should be_truthy; [@"I exist." writeToFile:URL.path atomically:YES encoding:NSUTF8StringEncoding error:NULL] should be_truthy; }); it(@"should pass for a file", ^{ expect(URL).to(exist); }); it(@"should pass for a directory", ^{ cacheURL should exist; }); afterEach(^{ [fileManager removeItemAtURL:URL error:NULL] should be_truthy; }); }); context(@"pointing to a nonexistent filesystem resource", ^{ beforeEach(^{ URL = [NSURL fileURLWithPath:@"/foo/bar/baz"]; [URL isFileURL] should be_truthy; }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to exist on the local filesystem", URL], ^{ expect(URL).to(exist); }); }); }); context(@"pointing to a non-filesystem resource", ^{ beforeEach(^{ URL = [NSURL URLWithString:@"http://zombo.com"]; [URL isFileURL] should_not be_truthy; }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to exist on the local filesystem", URL], ^{ expect(URL).to(exist); }); }); }); }); describe(@"when the actual value is an NSString *", ^{ __block NSString *path; context(@"pointing to a file path that exists", ^{ beforeEach(^{ path = [cacheURL URLByAppendingPathComponent:@"data.file"].path; [@"I exist." writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL] should be_truthy; }); it(@"should pass for a file", ^{ expect(path).to(exist); }); it(@"should pass for a directory", ^{ cacheURL.path should exist; }); afterEach(^{ [fileManager removeItemAtPath:path error:NULL] should be_truthy; }); }); context(@"pointing to a nonexistent file path", ^{ beforeEach(^{ path = @"/foo/bar/baz"; }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to exist on the local filesystem", path], ^{ expect(path).to(exist); }); }); }); context(@"pointing to a non-filesystem resource", ^{ beforeEach(^{ path = @"http://zombo.com"; }); it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to exist on the local filesystem", path], ^{ expect(path).to(exist); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/MutableEqualSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(MutableEqualSpec) describe(@"equal matcher", ^{ describe(@"when the actual value is an NSString *", ^{ NSString *actualValue = @"wibble"; describe(@"and the expected value is an NSMutableString *", ^{ __block NSMutableString *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSMutableString stringWithString:actualValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not equal <%@>", actualValue, expectedValue], ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSMutableString stringWithString:@"wobble"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to equal <%@>", actualValue, expectedValue], ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); describe(@"when the actual value is an NSMutableString *", ^{ NSMutableString *actualValue = [NSMutableString stringWithString:@"wibble"]; describe(@"and the expected value is an NSString *", ^{ __block NSString *expectedValue; describe(@"and the values are equal", ^{ beforeEach(^{ expectedValue = [NSString stringWithString:actualValue]; }); describe(@"positive match", ^{ it(@"should pass", ^{ expect(actualValue).to(equal(expectedValue)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not equal <%@>", actualValue, expectedValue], ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); describe(@"and the values are not equal", ^{ beforeEach(^{ expectedValue = [NSMutableString stringWithString:@"wobble"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to equal <%@>", actualValue, expectedValue], ^{ expect(actualValue).to(equal(expectedValue)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(actualValue).to_not(equal(expectedValue)); }); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/RaiseExceptionSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" @interface CustomException : NSException; @end @implementation CustomException; @end @interface SubclassException : CustomException; @end @implementation SubclassException; @end @interface AnotherSubclassException : CustomException; @end @implementation AnotherSubclassException; @end using namespace Cedar::Matchers; SPEC_BEGIN(RaiseExceptionSpec) describe(@"raise_exception matcher", ^{ __block void (^block)(); __block NSException *exception; context(@"with no exception class specified", ^{ context(@"when the block throws an exception", ^{ beforeEach(^{ exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Because" userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); context(@"when called with parentheses", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception", block], ^{ block should_not raise_exception; }); }); }); }); context(@"when called without parentheses", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception; }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception", block], ^{ block should_not raise_exception; }); }); }); }); }); context(@"when the block does not throw an exception", ^{ beforeEach(^{ block = [[^{} copy] autorelease]; }); context(@"when called with parentheses", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception", block], ^{ block should raise_exception; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception; }); }); }); context(@"when called without parentheses", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception", block], ^{ block should raise_exception; }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception; }); }); }); }); }); context(@"with an exception class specified", ^{ Class expectedExceptionClass = [CustomException class]; context(@"when the block throws an exception of that class", ^{ beforeEach(^{ exception = [expectedExceptionClass exceptionWithName:NSInternalInconsistencyException reason:@"Because" userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception(expectedExceptionClass); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception of class <%@>", block, NSStringFromClass(expectedExceptionClass)], ^{ block should_not raise_exception(expectedExceptionClass); }); }); }); }); context(@"when the block throws an exception of a sublass of the specified class", ^{ beforeEach(^{ exception = [SubclassException exceptionWithName:NSInternalInconsistencyException reason:@"Because" userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); context(@"when subclass exceptions are expected", ^{ describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception(expectedExceptionClass).or_subclass(); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception of class, or subclass of class, <%@>", block, NSStringFromClass([expectedExceptionClass class])], ^{ block should_not raise_exception(expectedExceptionClass).or_subclass(); }); }); }); }); context(@"when subclass exceptions are not expected", ^{ describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception of class <%@>", block, NSStringFromClass([expectedExceptionClass class])], ^{ block should raise_exception(expectedExceptionClass); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception(expectedExceptionClass); }); }); }); }); context(@"when the block throws an exception of an unrelated class", ^{ beforeEach(^{ exception = [AnotherSubclassException exceptionWithName:NSInternalInconsistencyException reason:@"Because" userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception of class <%@>", block, NSStringFromClass([expectedExceptionClass class])], ^{ block should raise_exception(expectedExceptionClass); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception(expectedExceptionClass); }); }); }); context(@"when the block does not throw an exception", ^{ beforeEach(^{ block = [[^{} copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception of class <%@>", block, NSStringFromClass([expectedExceptionClass class])], ^{ block should raise_exception(expectedExceptionClass); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception(expectedExceptionClass); }); }); }); }); context(@"with a reason specified", ^{ NSString *reason = @"Because of something you did."; context(@"when the block throws an exception with the specified reason", ^{ beforeEach(^{ exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception.with_reason(reason); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception with reason <%@>", block, reason], ^{ block should_not raise_exception.with_reason(reason); }); }); }); context(@"and the name is different", ^{ beforeEach(^{ exception = [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception.with_name(NSInvalidArgumentException).with_reason(reason); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception with name <%@> and reason <%@>", block, NSInvalidArgumentException, reason], ^{ block should_not raise_exception.with_name(NSInvalidArgumentException).with_reason(reason); }); }); }); }); }); context(@"when the block throws an exception with a different reason", ^{ NSString *anotherReason = @"It's not you, it's me"; beforeEach(^{ exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:anotherReason userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception with reason <%@>", block, reason], ^{ block should raise_exception.with_reason(reason); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception.with_reason(reason); }); }); }); context(@"when the block throws an exception which we compare to a string built at runtime", ^{ it(@"should not blow up when the autorelease pool drains", ^{ NSString *reason = [NSString stringWithFormat:@"Because we need to %@", @"test it."]; exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:reason userInfo:nil]; ^{ [exception raise]; } should raise_exception.with_name(NSInternalInconsistencyException).with_reason(reason); }); }); context(@"when the block does not throw an exception", ^{ beforeEach(^{ block = [[^{} copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception with reason <%@>", block, reason], ^{ block should raise_exception.with_reason(reason); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception.with_reason(reason); }); }); }); }); context(@"with a name specified", ^{ NSString *name = @"CDRSpecException"; context(@"when the block throws an exception with the specified name", ^{ beforeEach(^{ exception = [NSException exceptionWithName:name reason:nil userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should pass", ^{ block should raise_exception.with_name(name); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not raise an exception with name <%@>", block, name], ^{ block should_not raise_exception.with_name(name); }); }); }); }); context(@"when the block throws an exception with a different name", ^{ NSString *anotherName = @"CDRAnotherSpecException"; beforeEach(^{ exception = [NSException exceptionWithName:anotherName reason:nil userInfo:nil]; block = [[^{ [exception raise]; } copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception with name <%@>", block, name], ^{ block should raise_exception.with_name(name); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception.with_name(name); }); }); }); context(@"when the block does not throw an exception", ^{ beforeEach(^{ block = [[^{} copy] autorelease]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to raise an exception with name <%@>", block, name], ^{ block should raise_exception.with_name(name); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ block should_not raise_exception.with_name(name); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Base/RespondToSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" @interface TestResponder : NSObject + (void)classMethod; - (void)instanceMethod; @end @implementation TestResponder + (void)classMethod {} - (void)instanceMethod {} @end using namespace Cedar::Matchers; SPEC_BEGIN(RespondToSpec) describe(@"respond_to matcher", ^{ context(@"when called on class", ^{ __block Class subject = Nil; beforeEach(^{ subject = [TestResponder class]; }); afterEach(^{ subject = Nil; }); describe(@"positive match", ^{ it(@"should pass with selector", ^{ subject should respond_to(@selector(classMethod)); }); it(@"should pass with string", ^{ subject should respond_to("classMethod"); }); it(@"should fail with a sensible failure message", ^{ const char *methodName = "nonExistentClassMethod"; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to respond to <%s> selector", subject, methodName], ^{ subject should respond_to(methodName); }); }); }); describe(@"negative match", ^{ it(@"should pass with selector", ^{ subject should_not respond_to(NSSelectorFromString(@"nonExistentClassMethod")); }); it(@"should pass with string", ^{ subject should_not respond_to("nonExistentClassMethod"); }); it(@"should fail with a sensible failure message", ^{ const char *methodName = "classMethod"; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not respond to <%s> selector", subject, methodName], ^{ subject should_not respond_to(methodName); }); }); }); }); context(@"when called on instance", ^{ __block TestResponder *subject = nil; beforeEach(^{ subject = [[TestResponder new] autorelease]; }); afterEach(^{ subject = nil; }); describe(@"positive match", ^{ it(@"should pass with selector", ^{ subject should respond_to(@selector(instanceMethod)); }); it(@"should pass with string", ^{ subject should respond_to("instanceMethod"); }); it(@"should fail with a sensible failure message", ^{ const char *methodName = "nonExistentInstanceMethod"; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to respond to <%s> selector", subject, methodName], ^{ subject should respond_to(methodName); }); }); }); describe(@"negative match", ^{ it(@"should pass with selector", ^{ subject should_not respond_to(NSSelectorFromString(@"nonExistentInstanceMethod")); }); it(@"should pass with string", ^{ subject should_not respond_to("nonExistentInstanceMethod"); }); it(@"should fail with a sensible failure message", ^{ const char *methodName = "instanceMethod"; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not respond to <%s> selector", subject, methodName], ^{ subject should_not respond_to(methodName); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Container/BeEmptySpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(BeEmptySpec) describe(@"be_empty matcher", ^{ describe(@"when the value is an STL vector", ^{ describe(@"which is empty", ^{ std::vector container; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n)> to not be empty", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ std::vector container(2, 7); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n 7,\n 7\n)> to be empty", ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an STL map", ^{ describe(@"which is empty", ^{ std::map container; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{\n}> to not be empty", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ std::map container; container[5] = 6; container[7] = 10; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{\n 5 = 6;\n 7 = 10;\n}> to be empty", ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an STL set", ^{ describe(@"which is empty", ^{ std::set container; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{(\n)}> to not be empty", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ std::set container; container.insert(5); container.insert(7); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{(\n 5,\n 7\n)}> to be empty", ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSArray", ^{ describe(@"which is empty", ^{ NSArray *container = [NSArray array]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSArray *container = [NSArray arrayWithObjects:@"foo", @"bar", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSMutableArray", ^{ describe(@"which is empty", ^{ NSMutableArray *container = [NSMutableArray array]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSMutableArray *container = [NSMutableArray arrayWithObjects:@"foo", @"bar", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSDictionary", ^{ describe(@"which is empty", ^{ NSDictionary *container = [NSDictionary dictionary]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSDictionary *container = [NSDictionary dictionaryWithObjectsAndKeys:@"object1", @"key1", @"object2", @"key2", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSMutableDictionary", ^{ describe(@"which is empty", ^{ NSMutableDictionary *container = [NSMutableDictionary dictionary]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSMutableDictionary *container = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"object1", @"key1", @"object2", @"key2", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSSet", ^{ describe(@"which is empty", ^{ NSSet *container = [NSSet set]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSSet *container = [NSSet setWithObjects:@"object1", @"object2", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSMutableSet", ^{ describe(@"which is empty", ^{ NSMutableSet *container = [NSMutableSet set]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSMutableSet *container = [NSMutableSet setWithObjects:@"object1", @"object2", nil]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is an NSString", ^{ describe(@"which is empty", ^{ NSString *container = [NSString string]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not be empty", container], ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"which is not empty", ^{ NSString *container = [NSString stringWithFormat:@"not empty"]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to be empty", container], ^{ expect(container).to(be_empty); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(be_empty); }); }); }); }); describe(@"when the value is nil", ^{ it(@"should not match, and alert the user the value was nil", ^{ expectFailureWithMessage(@"Unexpected use of be_empty matcher to check for nil. The actual value was nil. This is probably not what you intended to verify.", ^{ id myNilValue = nil; expect(myNilValue).to(be_empty); }); }); }); }); describe(@"be_empty shorthand syntax (no parentheses)", ^{ NSArray *container = [NSArray array]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(be_empty); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <(\n)> to not be empty", ^{ expect(container).to_not(be_empty); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Container/ContainSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(ContainSpec) describe(@"contain matcher", ^{ NSString *element = @"element"; NSString *elementCopy = [[element mutableCopy] autorelease]; beforeEach(^{ expect(element).to(equal(elementCopy)); }); describe(@"when the container is an STL vector", ^{ describe(@"which contains the element", ^{ std::vector container(1, elementCopy); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <(\n %@\n)> to not contain <%@>", element, element], ^{ expect(container).to_not(contain(element)); }); }); }); }); describe(@"which does not contain the element", ^{ std::vector container; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <(\n)> to contain <%@>", element], ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"matching based on object class", ^{ std::vector container(1, elementCopy); describe(@"positive match", ^{ it(@"should pass when checking for an instance of the exact class", ^{ expect(container).to(contain(an_instance_of([elementCopy class]))); }); it(@"should not pass when checking for an instance of a superclass", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <(\n %@\n)> to contain ", element], ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); context(@"when including subclasses", ^{ it(@"should pass when checking for an instance of a superclass", ^{ expect(container).to(contain(an_instance_of([NSObject class]).or_any_subclass())); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <(\n %@\n)> to not contain ", element, [elementCopy class]], ^{ expect(container).to_not(contain(an_instance_of([elementCopy class]))); }); }); }); }); describe(@"with modifiers", ^{ std::vector container; it(@"should not allow the as_a_key() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should not allow the as_a_value() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); }); describe(@"when the container is an STL map", ^{ std::map container; container[@"aKey"] = elementCopy; context(@"plain containment", ^{ context(@"when matching a specific object", ^{ it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher with dictionary; use the .as_a_key() or .as_a_value() modifiers", ^{ expect(container).to(contain(element)); }); }); }); }); context(@"matching key containment", ^{ context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(@"aKey").as_a_key()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected <{\n aKey = element;\n}> to not contain nested as a key", ^{ expect(container).to_not(contain(@"aKey").nested().as_a_key()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([@"aKey" class])).as_a_key()); }); }); }); context(@"matching value containment", ^{ context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(elementCopy).as_a_value()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <{\n aKey = element;\n}> to not contain <%@> nested as a value", element], ^{ expect(container).to_not(contain(element).nested().as_a_value()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([elementCopy class])).as_a_value()); }); }); }); context(@"with invalid modifiers", ^{ it(@"should not allow both the as_a_key() and as_a_value() modifiers together", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher; use the .as_a_key() or .as_a_value() modifiers, but not both", ^{ expect(container).to(contain(@"aKey").as_a_key().as_a_value()); }); }); }); }); describe(@"when the container is an STL set", ^{ describe(@"which contains the element", ^{ std::set container; container.insert(elementCopy); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <{(\n %@\n)}> to not contain <%@>", element, element], ^{ expect(container).to_not(contain(element)); }); }); }); it(@"should not allow the as_a_key() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should not allow the as_a_value() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); describe(@"which does not contain the element", ^{ std::set container; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <{(\n)}> to contain <%@>", element], ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"matching based on object class", ^{ std::set container; container.insert(elementCopy); describe(@"positive match", ^{ it(@"should pass when checking for an instance of the exact class", ^{ expect(container).to(contain(an_instance_of([elementCopy class]))); }); it(@"should not pass when checking for an instance of a superclass", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <{(\n %@\n)}> to contain ", element], ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); context(@"when including subclasses", ^{ it(@"should pass when checking for an instance of a superclass", ^{ expect(container).to(contain(an_instance_of([NSObject class]).or_any_subclass())); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <{(\n %@\n)}> to not contain ", element, [elementCopy class]], ^{ expect(container).to_not(contain(an_instance_of([elementCopy class]))); }); }); }); }); }); sharedExamplesFor(@"nil container", ^(NSDictionary *sharedContext) { id container = nil; describe(@"positive match", ^{ it(@"should should fail", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); }); sharedExamplesFor(@"containing the element", ^(NSDictionary *sharedContext) { __block id container; beforeEach(^{ container = [sharedContext objectForKey:@"container"]; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@>", container, element], ^{ expect(container).to_not(contain(element)); }); }); }); it(@"should not allow the as_a_key() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should not allow the as_a_value() modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); sharedExamplesFor(@"not containing the element", ^(NSDictionary *sharedContext) { __block id container; beforeEach(^{ container = [sharedContext objectForKey:@"container_empty"]; }); describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); sharedExamplesFor(@"containing the element nested", ^(NSDictionary *sharedContext) { __block id container; beforeEach(^{ container = [sharedContext objectForKey:@"container_nested"]; }); describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element).nested()); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@> nested", container, element], ^{ expect(container).to_not(contain(element).nested()); }); }); }); describe(@"without the 'nested' modifier", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); }); sharedExamplesFor(@"matching based on object class", ^(NSDictionary *sharedContext) { __block id container; beforeEach(^{ container = sharedContext[@"container"]; }); describe(@"positive match", ^{ it(@"should pass when checking for an instance of the exact class", ^{ expect(container).to(contain(an_instance_of([elementCopy class]))); }); it(@"should not pass when checking for an instance of a superclass", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain ", container], ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); context(@"when including subclasses", ^{ it(@"should pass when checking for an instance of a superclass", ^{ expect(container).to(contain(an_instance_of([NSObject class]).or_any_subclass())); }); it(@"should not pass when checking for a different class", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain ", container], ^{ expect(container).to(contain(an_instance_of([NSNumber class]).or_any_subclass())); }); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain ", container, [elementCopy class]], ^{ expect(container).to_not(contain(an_instance_of([elementCopy class]))); }); }); }); }); describe(@"when the container is an NSArray", ^{ beforeEach(^{ [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSArray arrayWithObject:elementCopy] forKey:@"container"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSArray array] forKey:@"container_empty"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSArray arrayWithObject:[NSArray arrayWithObject:elementCopy]] forKey:@"container_nested"]; }); itShouldBehaveLike(@"nil container"); itShouldBehaveLike(@"containing the element"); itShouldBehaveLike(@"not containing the element"); itShouldBehaveLike(@"containing the element nested"); itShouldBehaveLike(@"matching based on object class"); }); describe(@"when the container is an NSMutableArray", ^{ beforeEach(^{ [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableArray arrayWithObject:elementCopy] forKey:@"container"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableArray array] forKey:@"container_empty"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableArray arrayWithObject:[NSMutableArray arrayWithObject:elementCopy]] forKey:@"container_nested"]; }); itShouldBehaveLike(@"nil container"); itShouldBehaveLike(@"containing the element"); itShouldBehaveLike(@"not containing the element"); itShouldBehaveLike(@"containing the element nested"); itShouldBehaveLike(@"matching based on object class"); }); describe(@"when the container is an NSSet", ^{ beforeEach(^{ [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSSet setWithObject:elementCopy] forKey:@"container"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSSet set] forKey:@"container_empty"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSSet setWithObject:[NSSet setWithObject:elementCopy]] forKey:@"container_nested"]; }); itShouldBehaveLike(@"nil container"); itShouldBehaveLike(@"containing the element"); itShouldBehaveLike(@"not containing the element"); itShouldBehaveLike(@"containing the element nested"); itShouldBehaveLike(@"matching based on object class"); }); describe(@"when the container is an NSMutableSet", ^{ beforeEach(^{ [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableSet setWithObject:elementCopy] forKey:@"container"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableSet set] forKey:@"container_empty"]; [[CDRSpecHelper specHelper].sharedExampleContext setObject:[NSMutableSet setWithObject:[NSSet setWithObject:elementCopy]] forKey:@"container_nested"]; }); itShouldBehaveLike(@"nil container"); itShouldBehaveLike(@"containing the element"); itShouldBehaveLike(@"not containing the element"); itShouldBehaveLike(@"containing the element nested"); itShouldBehaveLike(@"matching based on object class"); }); describe(@"when the container is an NSDictionary", ^{ context(@"plain containment", ^{ NSDictionary *container = [NSDictionary dictionary]; context(@"when matching a specific object", ^{ it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher with dictionary; use the .as_a_key() or .as_a_value() modifiers", ^{ expect(container).to(contain(element)); }); }); }); }); context(@"matching key containment", ^{ NSDictionary *container = [NSDictionary dictionaryWithObject:elementCopy forKey:@"aKey"]; context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(@"aKey").as_a_key()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain nested as a key", container], ^{ expect(container).to_not(contain(@"aKey").nested().as_a_key()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([@"aKey" class])).as_a_key()); }); }); }); context(@"matching value containment", ^{ NSDictionary *container = [NSDictionary dictionaryWithObject:elementCopy forKey:@"aKey"]; context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(elementCopy).as_a_value()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@> nested as a value", container, element], ^{ expect(container).to_not(contain(element).nested().as_a_value()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([elementCopy class])).as_a_value()); }); }); }); context(@"with invalid modifiers", ^{ NSDictionary *container = [NSDictionary dictionary]; it(@"should not allow both the as_a_key() and as_a_value() modifiers together", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher; use the .as_a_key() or .as_a_value() modifiers, but not both", ^{ expect(container).to(contain(@"aKey").as_a_key().as_a_value()); }); }); }); }); describe(@"when the container is an NSMutableDictionary", ^{ context(@"plain containment", ^{ NSMutableDictionary *container = [NSMutableDictionary dictionary]; context(@"when matching a specific object", ^{ it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher with dictionary; use the .as_a_key() or .as_a_value() modifiers", ^{ expect(container).to(contain(element)); }); }); }); }); context(@"matching key containment", ^{ NSDictionary *container = [NSDictionary dictionaryWithObject:elementCopy forKey:@"aKey"]; context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(@"aKey").as_a_key()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain nested as a key", container], ^{ expect(container).to_not(contain(@"aKey").nested().as_a_key()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([@"aKey" class])).as_a_key()); }); }); }); context(@"matching value containment", ^{ NSDictionary *container = [NSDictionary dictionaryWithObject:elementCopy forKey:@"aKey"]; context(@"when matching a specific object", ^{ context(@"positive match", ^{ it(@"should find the specified key", ^{ expect(container).to(contain(elementCopy).as_a_value()); }); }); context(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@> nested as a value", container, element], ^{ expect(container).to_not(contain(element).nested().as_a_value()); }); }); }); }); context(@"when matching a class", ^{ it(@"should find the matching class within the keys", ^{ expect(container).to(contain(an_instance_of([elementCopy class])).as_a_value()); }); }); }); context(@"with invalid modifiers", ^{ NSMutableDictionary *container = [NSMutableDictionary dictionary]; it(@"should not allow both the as_a_key() and as_a_value() modifiers together", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher; use the .as_a_key() or .as_a_value() modifiers, but not both", ^{ expect(container).to(contain(@"aKey").as_a_key().as_a_value()); }); }); }); }); describe(@"when the container is a C string", ^{ describe(@"which is null", ^{ char *container = NULL; describe(@"positive match", ^{ char *element = (char *)"foo"; it(@"should fail", ^{ expectFailureWithMessage(@"Expected to contain ", ^{ expect(container).to(contain(element)); }); }); }); }); describe(@"which contains the substring", ^{ char *container = (char *)"jack and jill"; char *element = (char *)"jack"; describe(@"positive match", ^{ it(@"should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not contain ", ^{ expect(container).to_not(contain(element)); }); }); }); }); describe(@"which does not contain the substring", ^{ char *container = (char *)"batman and robin"; char *element = (char *)"catwoman"; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to contain ", ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"with modifiers", ^{ char *container = (char *)"tom and jerry"; char *element = (char *)"tom"; it(@"should explode with the 'nested' modifier", ^{ expectExceptionWithReason(@"Unexpected use of 'nested' modifier on 'contain' matcher with string", ^{ expect(container).to(contain(element).nested()); }); }); it(@"should explode with the 'as_a_key' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should explode with the 'as_a_value' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); describe(@"matching based on object class", ^{ char *container = (char *)"foo"; it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher to check for an object in a string", ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); }); }); describe(@"when the container is a const C string", ^{ describe(@"which contains the substring", ^{ const char *container = (char *)"jack and jill"; const char *element = (char *)"jack"; describe(@"positive match", ^{ it(@"should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to not contain ", ^{ expect(container).to_not(contain(element)); }); }); }); }); describe(@"which does not contain the substring", ^{ const char *container = (char *)"batman and robin"; const char *element = (char *)"catwoman"; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage(@"Expected to contain ", ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"with modifiers", ^{ const char *container = "tom and jerry"; const char *element = "tom"; it(@"should explode with the 'nested' modifier", ^{ expectExceptionWithReason(@"Unexpected use of 'nested' modifier on 'contain' matcher with string", ^{ expect(container).to(contain(element).nested()); }); }); it(@"should explode with the 'as_a_key' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should explode with the 'as_a_value' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); describe(@"matching based on object class", ^{ const char *container = "foo"; it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher to check for an object in a string", ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); }); }); describe(@"when the container is an NSString", ^{ describe(@"which is nil", ^{ NSString *container = nil; describe(@"positive match", ^{ it(@"should should fail", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); }); describe(@"which contains the substring", ^{ NSString *container = @"A string that contains element"; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@>", container, element], ^{ expect(container).to_not(contain(element)); }); }); }); }); describe(@"which does not contain the substring", ^{ NSString *container = @"I contain nothing!"; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"with modifiers", ^{ NSString *container = @"tom and jerry"; NSString *element = @"tom"; it(@"should explode with the 'nested' modifier", ^{ expectExceptionWithReason(@"Unexpected use of 'nested' modifier on 'contain' matcher with string", ^{ expect(container).to(contain(element).nested()); }); }); it(@"should explode with the 'as_a_key' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should explode with the 'as_a_value' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); describe(@"matching based on object class", ^{ NSString *container = @"foo"; it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher to check for an object in a string", ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); }); }); describe(@"when the container is an NSMutableString", ^{ describe(@"which is nil", ^{ NSMutableString *container = nil; describe(@"positive match", ^{ it(@"should should fail", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); }); describe(@"which contains the substring", ^{ NSMutableString *container = [[@"A string that contains element" mutableCopy] autorelease]; describe(@"positive match", ^{ it(@"should should pass", ^{ expect(container).to(contain(element)); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@>", container, element], ^{ expect(container).to_not(contain(element)); }); }); }); }); describe(@"which does not contain the substring", ^{ NSMutableString *container = [[@"I contain nothing!" mutableCopy] autorelease]; describe(@"positive match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", container, element], ^{ expect(container).to(contain(element)); }); }); }); describe(@"negative match", ^{ it(@"should pass", ^{ expect(container).to_not(contain(element)); }); }); }); describe(@"with modifiers", ^{ NSMutableString *container = [[@"A string that contains element" mutableCopy] autorelease]; it(@"should explode with the 'nested' modifier", ^{ expectExceptionWithReason(@"Unexpected use of 'nested' modifier on 'contain' matcher with string", ^{ expect(container).to(contain(element).nested()); }); }); it(@"should explode with the 'as_a_key' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_key() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_key()); }); }); it(@"should explode with the 'as_a_value' modifier", ^{ expectExceptionWithReason(@"Unexpected use of the .as_a_value() modifier on the 'contain' matcher without a dictionary", ^{ expect(container).to(contain(element).as_a_value()); }); }); }); describe(@"matching based on object class", ^{ NSMutableString *container = [@"foo" mutableCopy]; it(@"should explode", ^{ expectExceptionWithReason(@"Unexpected use of 'contain' matcher to check for an object in a string", ^{ expect(container).to(contain(an_instance_of([NSObject class]))); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/Container/ContainSubsetSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(ContainSubsetSpec) describe(@"contain_subset matcher", ^{ context(@"when the container is a dictionary", ^{ NSDictionary *container = @{@"key": @"value", @"source": @"sink"}; __block id subset; describe(@"positive matches", ^{ beforeEach(^{ subset = @{@"key": @"value", @"source": @"sink"}; }); it(@"should contain itself as a subset", ^{ expect(container).to(contain_subset(subset)); }); }); describe(@"negative matches", ^{ context(@"when the key and value are not present at all", ^{ beforeEach(^{ subset = @{@"noway": @"josé"}; }); it(@"should not match", ^{ container should_not contain_subset(subset); }); it(@"should provide a nicely formatted message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain subset <%@>", container, subset], ^{ container should contain_subset(subset); }); }); }); context(@"when the values exist but belong to different keys", ^{ beforeEach(^{ subset = @{@"key": @"sink"}; }); it(@"should not match", ^{ container should_not contain_subset(subset); }); it(@"should provide a nicely formatted message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain subset <%@>", container, subset], ^{ container should contain_subset(subset); }); }); }); }); }); context(@"when the container is not a dictionary but is an Obj-C object", ^{ NSArray *weirdContainer = @[@"item1", @"item2"]; id subset = nil; it(@"should not match", ^{ expectExceptionWithReason(@"Unexpected use of the 'contain_subset' matcher with non-dictionary container <(\n item1,\n item2\n)>", ^{ weirdContainer should_not contain_subset(subset); }); }); }); context(@"when the container is not an Obj-C object", ^{ char *notAnObjCObject = (char *)"whoops i accidentally all the tests"; id subset = nil; it(@"should not match", ^{ expectExceptionWithReason(@"Unexpected use of the 'contain_subset' matcher with non-dictionary container ", ^{ notAnObjCObject should_not contain_subset(subset); }); }); }); context(@"when the subset is not a dictionary but is an Obj-C object", ^{ NSDictionary *container = @{}; NSString *subset = @"whoops!"; it(@"should not match", ^{ expectExceptionWithReason(@"Unexpected use of the 'contain_subset' matcher with non-dictionary subset ", ^{ container should_not contain_subset(subset); }); }); }); context(@"when the subset is not an Obj-C object", ^{ NSDictionary *container = @{}; char *notAnObject = (char *)"whoops!"; it(@"should not match", ^{ expectExceptionWithReason(@"Unexpected use of the 'contain_subset' matcher with non-dictionary subset ", ^{ container should_not contain_subset(notAnObject); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/ExpectFailureWithMessage.h ================================================ #import #import "CDRNullabilityCompat.h" #import "CDRExampleBase.h" NS_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif void expectFailureWithMessage(NSString *message, CDRSpecBlock block); void expectExceptionWithReason(NSString *reason, CDRSpecBlock block); #ifdef __cplusplus } #endif NS_ASSUME_NONNULL_END ================================================ FILE: Spec/Matchers/ExpectFailureWithMessage.mm ================================================ #import "ExpectFailureWithMessage.h" #import "CedarMatchers.h" #import "CDRSpecFailure.h" using namespace Cedar::Matchers; void expectFailureWithMessage(NSString *message, CDRSpecBlock block) { @try { block(); } @catch (CDRSpecFailure *x) { if (![message isEqualToString:x.reason]) { NSString *reason = [NSString stringWithFormat:@"Expected failure message: <%@> but received failure message <%@>", message, x.reason]; [[CDRSpecFailure specFailureWithReason:reason fileName:x.fileName lineNumber:x.lineNumber] raise]; } return; } fail(@"Expectation should have failed."); } void expectExceptionWithReason(NSString *reason, CDRSpecBlock block) { @try { block(); } @catch (CDRSpecFailure *x) { fail(@"Expected exception, but received failure."); } @catch (NSException *x) { if (![reason isEqualToString:x.reason]) { NSString *failureReason = [NSString stringWithFormat:@"Expected exception with reason: <%@> but received exception with reason <%@>", reason, x.reason]; fail(failureReason); } return; } fail(@"Expectation should have raised an exception."); } ================================================ FILE: Spec/Matchers/OSX/OSXGeometryEqualSpecSpec.mm ================================================ #import #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(OSXGeometryEqualSpecSpec) describe(@"CoreGraphics struct comparisons", ^{ describe(@"comparing CGRects", ^{ it(@"should be possible", ^{ CGRect thisRect = CGRectMake(10, 20, 30, 40); CGRect thatRect = CGRectMake(10, 20, 30, 40); thisRect should equal(thatRect); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{{10, 20}, {30, 40}}> to equal <{{11, 22}, {33, 44}}>", ^{ CGRect thisRect = CGRectMake(10, 20, 30, 40); CGRect thatRect = CGRectMake(11, 22, 33, 44); thisRect should equal(thatRect); }); }); }); describe(@"comparing CGSizes", ^{ it(@"should be possible", ^{ CGSize thisSize = CGSizeMake(10, 20); CGSize thatSize = CGSizeMake(10, 20); thisSize should equal(thatSize); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{10, 20}> to equal <{11, 22}>", ^{ CGSize thisSize = CGSizeMake(10, 20); CGSize thatSize = CGSizeMake(11, 22); thisSize should equal(thatSize); }); }); }); describe(@"comparing CGPoints", ^{ it(@"should be possible", ^{ CGPoint thisPoint = CGPointMake(10, 20); CGPoint thatPoint = CGPointMake(10, 20); thisPoint should equal(thatPoint); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{10, 20}> to equal <{11, 22}>", ^{ CGPoint thisPoint = CGPointMake(10, 20); CGPoint thatPoint = CGPointMake(11, 22); thisPoint should equal(thatPoint); }); }); }); describe(@"comparing CGAffineTransforms", ^{ it(@"should be possible", ^{ CGAffineTransform thisTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); CGAffineTransform thatTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); thisTransform should equal(thatTransform); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <[10, 20, 30, 40, 50, 60]> to equal <[11, 22, 33, 44, 55, 66]>", ^{ CGAffineTransform thisTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); CGAffineTransform thatTransform = CGAffineTransformMake(11, 22, 33, 44, 55, 66); thisTransform should equal(thatTransform); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/UIKit/UIKitContainSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(UIKitContainSpec) describe(@"UIKit contain matcher", ^{ describe(@"when the container is a UIView", ^{ __block UIView *parentView; __block UIView *childView; __block UIView *grandchildView; __block UIView *orphanView; beforeEach(^{ parentView = [[[UIView alloc] init] autorelease]; childView = [[[UIView alloc] init] autorelease]; grandchildView = [[[UIView alloc] init] autorelease]; orphanView = [[[UIView alloc] init] autorelease]; [parentView addSubview:childView]; [childView addSubview:grandchildView]; }); it(@"should pass for views that are subviews of the view", ^{ parentView should contain(childView); }); it(@"should fail for views that are nested subviews of the view", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", parentView, grandchildView], ^{ parentView should contain(grandchildView); }); }); it(@"should fail for views that are not contained by the view in its hierarchy", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", parentView, orphanView], ^{ parentView should contain(orphanView); }); }); describe(@"negative matcher", ^{ it(@"should pass for views that are not contained by the view in its hierarchy", ^{ parentView should_not contain(orphanView); }); it(@"should fail for views that are subviews of the view", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@>", parentView, childView], ^{ parentView should_not contain(childView); }); }); }); describe(@"with the 'nested' modifier", ^{ it(@"should pass for views that are nested subviews of the view", ^{ parentView should contain(grandchildView).nested(); }); describe(@"negative matcher", ^{ it(@"should fail for views that are nested subviews of the view", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@> nested", parentView, grandchildView], ^{ parentView should_not contain(grandchildView).nested(); }); }); }); }); describe(@"matching based on object class", ^{ describe(@"positive match", ^{ it(@"should pass when checking for an instance of the exact class", ^{ parentView should contain(an_instance_of([UIView class])); }); it(@"should not pass when checking for an instance of a superclass", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain ", parentView], ^{ parentView should contain(an_instance_of([UIResponder class])); }); }); context(@"when including subclasses", ^{ it(@"should pass when checking for an instance of a superclass", ^{ parentView should contain(an_instance_of([UIResponder class]).or_any_subclass()); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain ", parentView], ^{ parentView should_not contain(an_instance_of([UIView class])); }); }); }); }); }); describe(@"when the container is a CALayer", ^{ __block CALayer *parentLayer; __block CALayer *childLayer; __block CALayer *grandchildLayer; __block CALayer *orphanLayer; beforeEach(^{ parentLayer = [[[CALayer alloc] init] autorelease]; childLayer = [[[CALayer alloc] init] autorelease]; grandchildLayer = [[[CALayer alloc] init] autorelease]; orphanLayer = [[[CALayer alloc] init] autorelease]; [parentLayer addSublayer:childLayer]; [childLayer addSublayer:grandchildLayer]; }); it(@"should pass for layers that are sublayers of the layer", ^{ parentLayer should contain(childLayer); }); it(@"should fail for layers that are nested sublayers of the layer", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", parentLayer, grandchildLayer], ^{ parentLayer should contain(grandchildLayer); }); }); it(@"should fail for layers that are not contained by the layer in its hierarchy", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain <%@>", parentLayer, orphanLayer], ^{ parentLayer should contain(orphanLayer); }); }); describe(@"negative matcher", ^{ it(@"should pass for layers that are not contained by the layer in its hierarchy", ^{ parentLayer should_not contain(orphanLayer); }); it(@"should fail for layers that are sublayers of the layer", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@>", parentLayer, childLayer], ^{ parentLayer should_not contain(childLayer); }); }); }); describe(@"with the 'nested' modifier", ^{ it(@"should pass for layers that are nested sublayers of the layer", ^{ parentLayer should contain(grandchildLayer).nested(); }); describe(@"negative matcher", ^{ it(@"should fail for layers that are nested sublayers of the layer", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain <%@> nested", parentLayer, grandchildLayer], ^{ parentLayer should_not contain(grandchildLayer).nested(); }); }); }); }); describe(@"matching based on object class", ^{ describe(@"positive match", ^{ it(@"should pass when checking for an instance of the exact class", ^{ parentLayer should contain(an_instance_of([CALayer class])); }); it(@"should not pass when checking for an instance of a superclass", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to contain ", parentLayer], ^{ parentLayer should contain(an_instance_of([NSObject class])); }); }); context(@"when including subclasses", ^{ it(@"should pass when checking for an instance of a superclass", ^{ parentLayer should contain(an_instance_of([NSObject class]).or_any_subclass()); }); }); }); describe(@"negative match", ^{ it(@"should fail with a sensible failure message", ^{ expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not contain ", parentLayer], ^{ parentLayer should_not contain(an_instance_of([CALayer class])); }); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/Matchers/UIKit/UIKitEqualSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(UIKitEqualSpec) describe(@"CoreGraphics and UIGeometry struct comparisons", ^{ describe(@"comparing UIImages", ^{ it(@"should equal if they are the same instances", ^{ [UIImage imageNamed:@"image"] should equal([UIImage imageNamed:@"image"]); }); it(@"should equal if they are the same binary data", ^{ UIImage *image = [UIImage imageNamed:@"image"]; UIImage *binaryEquivalentImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1) resizingMode:UIImageResizingModeTile]; image should equal(binaryEquivalentImage); }); it(@"should not equal if they are different instances with different binary data", ^{ UIImage *image = [UIImage imageNamed:@"image"]; UIImage *differentImage = [UIImage imageNamed:@"edward.jpg"]; image should_not equal(differentImage); }); it(@"should fail with a reasonable message", ^{ UIImage *image = [UIImage imageNamed:@"image"]; expectFailureWithMessage([NSString stringWithFormat:@"Expected <%@> to not equal <%@>", image, image], ^{ image should_not equal(image); }); }); }); describe(@"comparing CGRects", ^{ it(@"should be possible", ^{ CGRect thisRect = CGRectMake(10, 20, 30, 40); CGRect thatRect = CGRectMake(10, 20, 30, 40); thisRect should equal(thatRect); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{{10, 20}, {30, 40}}> to equal <{{11, 22}, {33, 44}}>", ^{ CGRect thisRect = CGRectMake(10, 20, 30, 40); CGRect thatRect = CGRectMake(11, 22, 33, 44); thisRect should equal(thatRect); }); }); }); describe(@"comparing CGSizes", ^{ it(@"should be possible", ^{ CGSize thisSize = CGSizeMake(10, 20); CGSize thatSize = CGSizeMake(10, 20); thisSize should equal(thatSize); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{10, 20}> to equal <{11, 22}>", ^{ CGSize thisSize = CGSizeMake(10, 20); CGSize thatSize = CGSizeMake(11, 22); thisSize should equal(thatSize); }); }); }); describe(@"comparing CGPoints", ^{ it(@"should be possible", ^{ CGPoint thisPoint = CGPointMake(10, 20); CGPoint thatPoint = CGPointMake(10, 20); thisPoint should equal(thatPoint); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{10, 20}> to equal <{11, 22}>", ^{ CGPoint thisPoint = CGPointMake(10, 20); CGPoint thatPoint = CGPointMake(11, 22); thisPoint should equal(thatPoint); }); }); }); describe(@"comparing UIEdgeInsets", ^{ it(@"should be possible", ^{ UIEdgeInsets theseInsets = UIEdgeInsetsMake(10, 20, 30, 40); UIEdgeInsets thoseInsets = UIEdgeInsetsMake(10, 20, 30, 40); theseInsets should equal(thoseInsets); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <{10, 20, 30, 40}> to equal <{11, 22, 33, 44}>", ^{ UIEdgeInsets theseInsets = UIEdgeInsetsMake(10, 20, 30, 40); UIEdgeInsets thoseInsets = UIEdgeInsetsMake(11, 22, 33, 44); theseInsets should equal(thoseInsets); }); }); }); describe(@"comparing CGAffineTransforms", ^{ it(@"should be possible", ^{ CGAffineTransform thisTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); CGAffineTransform thatTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); thisTransform should equal(thatTransform); }); it(@"should fail with a reasonable message", ^{ expectFailureWithMessage(@"Expected <[10, 20, 30, 40, 50, 60]> to equal <[11, 22, 33, 44, 55, 66]>", ^{ CGAffineTransform thisTransform = CGAffineTransformMake(10, 20, 30, 40, 50, 60); CGAffineTransform thatTransform = CGAffineTransformMake(11, 22, 33, 44, 55, 66); thisTransform should equal(thatTransform); }); }); }); }); SPEC_END ================================================ FILE: Spec/ObjCHeadersSpec.mm ================================================ #if TARGET_OS_IPHONE // Normally you would include this file out of the framework. However, we're // testing the framework here, so including the file from the framework will // conflict with the compiler attempting to include the file from the project. #import "Cedar-iOS.h" #else #import #endif // https://github.com/cedarbdd/cedar/issues/53 sums things up nicely #if defined(_OBJC_RUNTIME_H) || defined(_OBJC_MESSAGE_H) #error Objective-C runtime headers should not be exposed via public headers #endif ================================================ FILE: Spec/Reporters/CDRDefaultReporterSpec.mm ================================================ #import "Cedar.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; @interface TestCDRDefaultReporter : CDRDefaultReporter @property (nonatomic, retain) NSMutableString *reporter_output; @end @implementation TestCDRDefaultReporter - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString { if (self = [super initWithCedarVersion:cedarVersionString]) { self.reporter_output = [NSMutableString string]; } return self; } - (void)dealloc { self.reporter_output = nil; [super dealloc]; } - (void)logText:(NSString *)linePartial { [self.reporter_output appendString:linePartial]; } @end SPEC_BEGIN(CDRDefaultReporterSpec) describe(@"CDRDefaultReporter", ^{ __block TestCDRDefaultReporter *reporter; NSString *cedarVersionString = @"0.1.2 (a71e8f)"; beforeEach(^{ reporter = [[[TestCDRDefaultReporter alloc] initWithCedarVersion:cedarVersionString] autorelease]; }); describe(@"starting the test run", ^{ beforeEach(^{ [reporter runWillStartWithGroups:@[] andRandomSeed:1234]; }); it(@"should report the Cedar version", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Cedar Version: %@", cedarVersionString]); }); it(@"should report the random seed", ^{ reporter.reporter_output should contain(@"Running With Random Seed: 1234"); }); }); context(@"when adding one group", ^{ __block CDRExampleGroup *group; beforeEach(^{ group = [[[CDRExampleGroup alloc] initWithText:@"example group" isRoot:YES] autorelease]; }); context(@"with one child 'it' example", ^{ it(@"exampleCount should be 1", ^{ CDRExample *example = [[[CDRExample alloc] initWithText:@"example" andBlock:^{ }] autorelease]; [group add:example]; [reporter runWillStartWithGroups:@[group] andRandomSeed:33]; [reporter runWillStartExampleGroup:group]; [reporter runWillStartExample:example]; [example runWithDispatcher:nil]; [reporter runDidFinishExample:example]; [reporter runDidFinishExampleGroup:group]; [reporter runDidComplete]; [reporter exampleCount] should equal(1); }); }); context(@"with no child 'it' examples", ^{ it(@"exampleCount should be 0", ^{ [reporter runWillStartWithGroups:@[group] andRandomSeed:33]; [reporter runDidComplete]; [reporter exampleCount] should equal(0); }); }); }); }); SPEC_END ================================================ FILE: Spec/Reporters/CDRJUnitXMLReporterSpec.mm ================================================ #import "Cedar.h" #import "GDataXMLNode.h" #import "ExampleWithPublicRunDates.h" using namespace Cedar::Matchers; // Test class overrides actually writing XML to a file for speed and easier assertions @interface TestCDRJUnitXMLReporter : CDRJUnitXMLReporter { @private NSString *xml_; GDataXMLDocument *xmlDocument_; GDataXMLElement *xmlRootElement_; } @property (nonatomic, copy) NSString *xml; @property (nonatomic, strong) GDataXMLDocument *xmlDocument; @property (nonatomic, strong) GDataXMLElement *xmlRootElement; @end @implementation TestCDRJUnitXMLReporter @synthesize xml = xml_; @synthesize xmlDocument = xmlDocument_; @synthesize xmlRootElement = xmlRootElement_; - (instancetype)initWithCedarVersion:(NSString *)cedarVersionString { if (self = [super initWithCedarVersion:cedarVersionString]) { } return self; } - (void)dealloc { self.xml = nil; self.xmlRootElement = nil; self.xmlDocument = nil; [super dealloc]; } - (void)writeXmlToFile:(NSString *)xmlString { self.xml = xmlString; } // Temporarily redirect stdout to avoid unnecessary output when running tests - (void)runDidComplete { FILE *realStdout = stdout; stdout = fopen("/dev/null", "w"); @try { [super runDidComplete]; } @finally { fclose(stdout); stdout = realStdout; } self.xmlDocument = [[[GDataXMLDocument alloc] initWithXMLString:self.xml options:0 error:nil] autorelease]; self.xmlRootElement = self.xmlDocument.rootElement; } @end // Allow setting state for testing purposes @interface CDRExample (SpecPrivate) - (void)setState:(CDRExampleState)state; @end @implementation CDRExample (Spec) + (id)exampleWithText:(NSString *)text andState:(CDRExampleState)state { CDRExample *example = [[self class] exampleWithText:text andBlock:^{}]; [example setState:state]; return example; } @end SPEC_BEGIN(CDRJUnitXMLReporterSpec) describe(@"runDidComplete", ^{ __block TestCDRJUnitXMLReporter *reporter; NSString *cedarVersionString = @"0.1.2 (a71e8f)"; beforeEach(^{ reporter = [[[TestCDRJUnitXMLReporter alloc] initWithCedarVersion:cedarVersionString] autorelease]; }); context(@"when no specs are run", ^{ it(@"should output a blank test suite report", ^{ [reporter runDidComplete]; expect(reporter.xmlDocument).to_not(be_nil); expect(reporter.xmlRootElement).to_not(be_nil); expect(reporter.xmlRootElement.name).to(equal(@"testsuite")); }); }); describe(@"each passing spec", ^{ it(@"should be written to the XML file", ^{ CDRExample *example1 = [CDRExample exampleWithText:@"Passing spec 1" andState:CDRExampleStatePassed]; [reporter reportOnExample:example1]; CDRExample *example2 = [CDRExample exampleWithText:@"Passing spec 2" andState:CDRExampleStatePassed]; [reporter reportOnExample:example2]; [reporter runDidComplete]; expect(reporter.xmlDocument).to_not(be_nil); expect(reporter.xmlRootElement).to_not(be_nil); NSArray *testCases = [reporter.xmlRootElement elementsForName:@"testcase"]; expect(testCases.count).to(equal(2)); GDataXMLElement *example1XML = [testCases objectAtIndex:0]; expect([[example1XML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); expect([[example1XML attributeForName:@"name"] stringValue]).to(equal(@"Passing spec 1")); GDataXMLElement *example2XML = [testCases objectAtIndex:1]; expect([[example2XML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); expect([[example2XML attributeForName:@"name"] stringValue]).to(equal(@"Passing spec 2")); }); it(@"should have its name escaped", ^{ NSString *stringToEscape = @"Special ' characters \" should < be & escaped > "; CDRExample *example = [CDRExample exampleWithText:stringToEscape andState:CDRExampleStatePassed]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"name"] stringValue]).to(equal(stringToEscape)); }); it(@"should have its running time", ^{ ExampleWithPublicRunDates *example = [ExampleWithPublicRunDates exampleWithText:@"Running task" andState:CDRExampleStatePassed]; NSDate *startDate = [NSDate date]; [example setStartDate:startDate]; [example setEndDate:[startDate dateByAddingTimeInterval:5]]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"time"] stringValue]).to_not(be_nil); expect([[[exampleXML attributeForName:@"time"] stringValue] floatValue]).to(be_close_to(5)); }); it(@"should have it's classname", ^{ CDRExample *example = [CDRExample exampleWithText:@"Spec" andState:CDRExampleStatePassed]; example.spec = [[CDRSpec new] autorelease]; [reporter reportOnExample:example]; CDRExample *junitExample = [CDRExample exampleWithText:@"JUnitExample" andState:CDRExampleStatePassed]; junitExample.spec = [[CDRJUnitXMLReporterSpec new] autorelease]; [reporter reportOnExample:junitExample]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"classname"] stringValue]).to(equal(@"CDRSpec")); GDataXMLElement *junitExampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:1]; expect([[junitExampleXML attributeForName:@"classname"] stringValue]).to(equal(@"CDRJUnitXMLReporterSpec")); }); it(@"should have it's classname to default value if spec filename is empty", ^{ CDRExample *example = [CDRExample exampleWithText:@"Spec" andState:CDRExampleStatePassed]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); }); }); describe(@"each failing spec", ^{ it(@"should be written to the XML file", ^{ CDRExample *example1 = [CDRExample exampleWithText:@"Failing spec 1" andState:CDRExampleStateFailed]; example1.failure = [CDRSpecFailure specFailureWithReason:@"Failure reason 1"]; [reporter reportOnExample:example1]; CDRExample *example2 = [CDRExample exampleWithText:@"Failing spec 2" andState:CDRExampleStateFailed]; example2.failure = [CDRSpecFailure specFailureWithReason:@"Failure reason 2"]; [reporter reportOnExample:example2]; [reporter runDidComplete]; NSArray *testCases = [reporter.xmlRootElement elementsForName:@"testcase"]; expect(testCases.count).to(equal(2)); GDataXMLElement *example1XML = [testCases objectAtIndex:0]; expect([[example1XML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); expect([[example1XML attributeForName:@"name"] stringValue]).to(equal(@"Failing spec 1")); expect([[[example1XML nodesForXPath:@"failure/@type" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure")); expect([[[example1XML nodesForXPath:@"failure/text()" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure reason 1")); GDataXMLElement *example2XML = [testCases objectAtIndex:1]; expect([[example2XML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); expect([[example2XML attributeForName:@"name"] stringValue]).to(equal(@"Failing spec 2")); expect([[[example2XML nodesForXPath:@"failure/@type" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure")); expect([[[example2XML nodesForXPath:@"failure/text()" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure reason 2")); }); it(@"should have its name escaped", ^{ NSString *stringToEscape = @"Special ' characters \" should < be & escaped > "; CDRExample *example = [CDRExample exampleWithText:stringToEscape andState:CDRExampleStateFailed]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"name"] stringValue]).to(equal(stringToEscape)); }); it(@"should escape the failure reason", ^{ NSString *exampleName = @"Failing spec 1"; NSString *failureReason = @" Special ' characters \" should < be & escaped > "; NSString *fullExampleText = [NSString stringWithFormat:@"%@\n%@", exampleName, failureReason]; CDRExample *example = [CDRExample exampleWithText:fullExampleText andState:CDRExampleStateFailed]; example.failure = [CDRSpecFailure specFailureWithReason:failureReason]; [reporter reportOnExample:example]; [reporter runDidComplete]; expect([[[reporter.xmlRootElement nodesForXPath:@"testcase/failure/text()" error:nil] objectAtIndex:0] stringValue]).to(equal(failureReason)); }); it(@"should have its running time", ^{ ExampleWithPublicRunDates *example = [ExampleWithPublicRunDates exampleWithText:@"Failing spec\nFailure reason" andState:CDRExampleStateFailed]; NSDate *startDate = [NSDate date]; [example setStartDate:startDate]; [example setEndDate:[startDate dateByAddingTimeInterval:5]]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"time"] stringValue]).to_not(be_nil); expect([[[exampleXML attributeForName:@"time"] stringValue] floatValue]).to(be_close_to(5)); }); it(@"should have it's classname", ^{ CDRExample *example = [CDRExample exampleWithText:@"Spec" andState:CDRExampleStateFailed]; example.spec = [[CDRSpec new] autorelease]; [reporter reportOnExample:example]; CDRExample *junitExample = [CDRExample exampleWithText:@"JUnitExample" andState:CDRExampleStateFailed]; junitExample.spec = [[CDRJUnitXMLReporterSpec new] autorelease]; [reporter reportOnExample:junitExample]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"classname"] stringValue]).to(equal(@"CDRSpec")); GDataXMLElement *junitExampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:1]; expect([[junitExampleXML attributeForName:@"classname"] stringValue]).to(equal(@"CDRJUnitXMLReporterSpec")); }); it(@"should have it's classname to default value if spec filename is empty", ^{ CDRExample *example = [CDRExample exampleWithText:@"Spec" andState:CDRExampleStateFailed]; [reporter reportOnExample:example]; [reporter runDidComplete]; GDataXMLElement *exampleXML = [[reporter.xmlRootElement elementsForName:@"testcase"] objectAtIndex:0]; expect([[exampleXML attributeForName:@"classname"] stringValue]).to(equal(@"Cedar")); }); }); describe(@"each spec that causes an error", ^{ it(@"should be handled the same as a failing spec", ^{ CDRExample *example = [CDRExample exampleWithText:@"Failing spec\nFailure reason" andState:CDRExampleStateError]; [reporter reportOnExample:example]; [reporter runDidComplete]; expect([[[reporter.xmlRootElement nodesForXPath:@"testcase/@classname" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Cedar")); expect([[[reporter.xmlRootElement nodesForXPath:@"testcase/@name" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failing spec")); expect([[[reporter.xmlRootElement nodesForXPath:@"testcase/failure/@type" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure")); expect([[[reporter.xmlRootElement nodesForXPath:@"testcase/failure/text()" error:nil] objectAtIndex:0] stringValue]).to(equal(@"Failure reason")); }); }); }); SPEC_END ================================================ FILE: Spec/Reporters/CDROTestReporterSpec.mm ================================================ #import "Cedar.h" #import "CDRReportDispatcher.h" #import static char *testReporterLogKey; @interface CDROTestReporter (SpecOverrides) - (void)logMessage:(NSString *)message; - (NSMutableString *)reporter_output; - (void)setReporter_output:(NSMutableString *)value; @end @implementation CDROTestReporter (SpecOverrides) - (void)logMessage:(NSString *)message { [self.reporter_output appendFormat:@"%@\n", message]; } - (NSMutableString *)reporter_output { return objc_getAssociatedObject(self, &testReporterLogKey); } - (void)setReporter_output:(NSMutableString *)value { objc_setAssociatedObject(self, &testReporterLogKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end @interface MyExampleSpec : CDRSpec @end @implementation MyExampleSpec - (void)declareBehaviors {} @end using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDROTestReporterSpec) describe(@"CDROTestReporter", ^{ __block CDROTestReporter *reporter; __block CDRSpec *spec1, *spec2; __block CDRExampleGroup *group1, *group2, *focusedGroup; __block CDRExample *passingExample, *failingExample, *focusedExample; __block NSString *bundleName; __block CDRReportDispatcher *dispatcher; NSString *cedarVersionString = @"0.1.2 (a71e8f)"; beforeEach(^{ bundleName = [NSBundle mainBundle].bundleURL.pathComponents.lastObject; reporter = [[[CDROTestReporter alloc] initWithCedarVersion:cedarVersionString] autorelease]; reporter.reporter_output = [NSMutableString string]; dispatcher = [[[CDRReportDispatcher alloc] initWithReporters:@[reporter]] autorelease]; spec1 = [[[CDRSpec alloc] init] autorelease]; spec2 = [[[MyExampleSpec alloc] init] autorelease]; group1 = [CDRExampleGroup groupWithText:@"my group"]; group1.spec = spec1; group2 = [CDRExampleGroup groupWithText:@"my group other"]; group2.spec = spec2; passingExample = [CDRExample exampleWithText:@"passing" andBlock:^{}]; passingExample.spec = spec1; failingExample = [CDRExample exampleWithText:@"failing" andBlock:^{fail(@"whale");}]; failingExample.spec = spec1; focusedGroup = [CDRExampleGroup groupWithText:@"laser"]; focusedExample = [CDRExample exampleWithText:@"focus" andBlock:^{}]; focusedGroup.focused = YES; [focusedGroup add:focusedExample]; focusedGroup.spec = spec1; }); afterEach(^{ reporter.reporter_output = nil; }); describe(@"starting the test run", ^{ context(@"when not focused", ^{ beforeEach(^{ [dispatcher runWillStartWithGroups:@[group1] andRandomSeed:1337]; }); it(@"should report the Cedar version", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Cedar Version: %@", cedarVersionString]); }); it(@"should report the random seed", ^{ reporter.reporter_output should contain(@"Cedar Random Seed: 1337"); }); it(@"should report that all tests are running", ^{ reporter.reporter_output should contain(@"Test Suite 'All tests' started at"); }); it(@"should report the test bundle suite", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Test Suite '%@' started at", bundleName]); }); }); context(@"when focused", ^{ __block BOOL originalState; beforeEach(^{ originalState = [CDRSpecHelper specHelper].shouldOnlyRunFocused; [CDRSpecHelper specHelper].shouldOnlyRunFocused = YES; [dispatcher runWillStartWithGroups:@[focusedGroup] andRandomSeed:34]; }); afterEach(^{ [CDRSpecHelper specHelper].shouldOnlyRunFocused = originalState; }); it(@"should report the Cedar version", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Cedar Version: %@", cedarVersionString]); }); it(@"should report the random seed", ^{ reporter.reporter_output should contain(@"Cedar Random Seed: 34"); }); it(@"should report that a subset of tests are running", ^{ reporter.reporter_output should contain(@"Test Suite 'Multiple Selected Tests' started at"); }); it(@"should report the test bundle suite", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Test Suite '%@' started at", bundleName]); }); }); }); describe(@"finishing the run", ^{ context(@"when not focused", ^{ beforeEach(^{ [dispatcher runWillStartWithGroups:@[group1] andRandomSeed:1337]; reporter.reporter_output = [NSMutableString string]; [dispatcher runDidComplete]; }); it(@"should report the end of all the tests", ^{ reporter.reporter_output should contain(@"Test Suite 'All tests' finished at"); }); it(@"should report the test bundle suite stats", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Test Suite '%@' finished at", bundleName]); }); }); context(@"when focused", ^{ __block BOOL originalState; beforeEach(^{ originalState = [CDRSpecHelper specHelper].shouldOnlyRunFocused; [CDRSpecHelper specHelper].shouldOnlyRunFocused = YES; [dispatcher runWillStartWithGroups:@[focusedGroup] andRandomSeed:42]; reporter.reporter_output = [NSMutableString string]; [dispatcher runDidComplete]; }); afterEach(^{ [CDRSpecHelper specHelper].shouldOnlyRunFocused = originalState; }); it(@"should report the end of all the tests", ^{ reporter.reporter_output should contain(@"Test Suite 'Multiple Selected Tests' finished at"); }); it(@"should report the test bundle suite stats", ^{ reporter.reporter_output should contain([NSString stringWithFormat:@"Test Suite '%@' finished at", bundleName]); }); }); }); describe(@"processing an example", ^{ beforeEach(^{ [group1 add:passingExample]; [group1 add:failingExample]; [spec1.rootGroup add:group1]; [dispatcher runWillStartWithGroups:@[spec1.rootGroup] andRandomSeed:1337]; reporter.reporter_output = [NSMutableString string]; [group1 runWithDispatcher:dispatcher]; }); it(@"should report the spec class", ^{ reporter.reporter_output should contain(@"Test Suite 'CDRSpec' started at"); }); it(@"should report the spec class finishing after the run completes", ^{ [dispatcher runDidComplete]; reporter.reporter_output should contain(@"Test Suite 'CDRSpec' finished at"); reporter.reporter_output should contain(@"Executed 2 tests, with 1 failure (0 unexpected) in"); }); it(@"should report the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_passing]' started."); }); it(@"should finish the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_passing]' passed ("); }); it(@"should report the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_failing]' started."); }); it(@"should finish the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_failing]' failed ("); }); }); describe(@"processing multiple spec classes", ^{ beforeEach(^{ [group1 add:passingExample]; CDRExampleGroup *anotherPassing = [CDRExample exampleWithText:@"another_passing" andBlock:^{}]; anotherPassing.spec = spec1; [group1 add:anotherPassing]; [spec1.rootGroup add:group1]; [group2 add:failingExample]; group2.spec = spec2; failingExample.spec = spec2; CDRExample *pendingExample = [CDRExample exampleWithText:@"pending" andBlock:nil]; pendingExample.spec = spec2; [group2 add:pendingExample]; [spec2.rootGroup add:group2]; [dispatcher runWillStartWithGroups:@[spec1.rootGroup, spec2.rootGroup] andRandomSeed:1337]; reporter.reporter_output = [NSMutableString string]; [group1 runWithDispatcher:dispatcher]; [group2 runWithDispatcher:dispatcher]; }); it(@"should report the spec class", ^{ reporter.reporter_output should contain(@"Test Suite 'CDRSpec' started at"); }); it(@"should report the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_passing]' started."); }); it(@"should finish the passing example", ^{ reporter.reporter_output should contain(@"Test Case '-[CDRSpec my_group_passing]' passed"); }); it(@"should report the spec class finishing after the run completes", ^{ [dispatcher runDidComplete]; reporter.reporter_output should contain(@"Test Suite 'CDRSpec' finished at"); NSRange range = [reporter.reporter_output rangeOfString:@"Test Suite 'CDRSpec' finished at"]; [reporter.reporter_output substringFromIndex:range.location] should contain(@"Executed 3 tests, with 1 failure (0 unexpected) in"); }); it(@"should report the failing example", ^{ reporter.reporter_output should contain(@"Test Case '-[MyExampleSpec my_group_other_failing]' started."); }); it(@"should report the failing example's error", ^{ reporter.reporter_output should contain(@": error: -[MyExampleSpec my_group_other_failing] :"); }); it(@"should finish the failing example", ^{ reporter.reporter_output should contain(@"Test Case '-[MyExampleSpec my_group_other_failing]' failed"); }); it(@"should not report the pending example", ^{ reporter.reporter_output should_not contain(@"Test Case '-[MyExampleSpec my_group_other_pending]'"); }); }); }); SPEC_END ================================================ FILE: Spec/ShouldSyntaxSpec.mm ================================================ #import "Cedar.h" #import "ExpectFailureWithMessage.h" using namespace Cedar::Matchers; SPEC_BEGIN(ShouldSyntaxSpec) describe(@"Should syntax", ^{ describe(@"should", ^{ it(@"should work with positive case", ^{ 3 should equal(3); }); it(@"should work correctly with operator precendence", ^{ 1 + 2 should equal(3); }); it(@"should work with negative case", ^{ expectFailureWithMessage(@"Expected <3> to equal <4>", ^{ 3 should equal(4); }); }); }); describe(@"should_not", ^{ it(@"should work with positive case", ^{ 3 should_not equal(4); }); it(@"should work with negative case", ^{ expectFailureWithMessage(@"Expected <3> to not equal <3>", ^{ 3 should_not equal(3); }); }); }); }); SPEC_END ================================================ FILE: Spec/SpecBundle/OS X Host App/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIconFile CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSPrincipalClass NSApplication ================================================ FILE: Spec/SpecBundle/OS X Host App/main.m ================================================ #import int main(int argc, const char * argv[]) { return NSApplicationMain(argc, argv); } ================================================ FILE: Spec/SpecBundle/SpecBundle-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 NSPrincipalClass TestObservationHelper ================================================ FILE: Spec/SpecBundle/SpecBundleApplicationTests.mm ================================================ #import "Cedar.h" #import "iOSHostAppDelegate.h" // should NOT be included in Cedar iOS SpecBundle target using namespace Cedar::Matchers; SPEC_BEGIN(SpecBundleApplicationTests) describe(@"A spec file testing UI", ^{ it(@"should run", ^{ UILabel *label = [[[UILabel alloc] init] autorelease]; expect([label class]).to(equal([UILabel class])); }); it(@"should be able to access classes that are included in the app bundle but are not directly included in the application tests bundle", ^{ // For that to work app target must have 'Strip Debug Symbols During Copy' set to NO. expect([iOSHostAppDelegate class]).to(equal([iOSHostAppDelegate class])); }); it(@"should have its main bundle set to be the app bundle", ^{ expect([[NSBundle mainBundle].bundlePath hasSuffix:@".app"]).to(be_truthy()); }); it(@"should be able to load nib files from the app bundle", ^{ NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"DummyView" owner:nil options:nil]; expect([views lastObject]).to(be_instance_of([UIView class])); }); }); SPEC_END ================================================ FILE: Spec/SpecBundle/SpecBundleApplicationTestsWithXCTest.m ================================================ #import #import "TestObservationHelper.h" @interface ExampleApplicationTestsWithXCTest : XCTestCase @end @implementation ExampleApplicationTestsWithXCTest - (void)testMainBundleIsTheAppBundle { XCTAssertTrue([[NSBundle mainBundle].bundlePath hasSuffix:@".app"], @"expected main NSBundle path to have 'app' extension"); } - (void)testRunningCedarExamples { NSArray *knownTestSuites = [TestObservationHelper knownTestSuites]; XCTAssert([[knownTestSuites valueForKeyPath:@"@unionOfArrays.tests.name"] containsObject:@"Cedar"]); } @end ================================================ FILE: Spec/SpecBundle/Support/TestObservationHelper.h ================================================ #import @interface TestObservationHelper : NSObject + (NSArray *)knownTestSuites; @end ================================================ FILE: Spec/SpecBundle/Support/TestObservationHelper.m ================================================ #import "TestObservationHelper.h" #import "CDRXCTestSupport.h" @interface XCTestSuite + (instancetype)defaultTestSuite; @end @interface TestObservationHelper () @end // This class is loaded as the NSPrincipalClass of test bundles that require it, at which point // it registers itself as a test observer. @implementation TestObservationHelper static NSMutableArray *_knownTestSuites; - (instancetype)init { if (self = [super init]) { Class observationCenterClass = NSClassFromString(@"XCTestObservationCenter"); if (observationCenterClass && [observationCenterClass respondsToSelector:@selector(sharedTestObservationCenter)]) { _knownTestSuites = [NSMutableArray array]; [[observationCenterClass sharedTestObservationCenter] addTestObserver:self]; } } return self; } + (NSArray *)knownTestSuites { return [_knownTestSuites copy] ?: @[[XCTestSuite defaultTestSuite]]; } - (void)testSuiteWillStart:(XCTestSuite *)suite { [_knownTestSuites addObject:suite]; } @end ================================================ FILE: Spec/SpecBundle/iOS Host App/en.lproj/DummyView.xib ================================================ ================================================ FILE: Spec/SpecBundle/iOS Host App/iOSHostAppDelegate.h ================================================ #import @interface iOSHostAppDelegate : NSObject @property (nonatomic, retain) IBOutlet UIWindow *window; @end ================================================ FILE: Spec/SpecBundle/iOS Host App/iOSHostAppDelegate.m ================================================ #import "iOSHostAppDelegate.h" @implementation iOSHostAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window.rootViewController = [[[UIViewController alloc] init] autorelease]; [self.window makeKeyAndVisible]; return YES; } - (void)dealloc { [_window release]; [super dealloc]; } @end ================================================ FILE: Spec/SpecBundle/iOS Host App/main.m ================================================ #import #import "iOSHostAppDelegate.h" int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([iOSHostAppDelegate class])); } } ================================================ FILE: Spec/SpecSpec.mm ================================================ #import "Cedar.h" using namespace Cedar::Matchers; void expectFailure(CDRSpecBlock block) { @try { block(); } @catch (CDRSpecFailure *) { return; } fail(@"Expectation should have failed."); } static NSString *globalValue__; SPEC_BEGIN(SpecSpec) describe(@"Spec", ^{ beforeEach(^{ // NSLog(@"=====================> I should run before all specs."); }); afterEach(^{ // NSLog(@"=====================> I should run after all specs."); }); describe(@"a nested spec", ^{ beforeEach(^{ // NSLog(@"=====================> I should run only before the nested specs."); }); afterEach(^{ // NSLog(@"=====================> I should run only after the nested specs."); }); it(@"should also run", ^{ // NSLog(@"=====================> Nested spec"); }); it(@"should also also run", ^{ // NSLog(@"=====================> Another nested spec"); }); }); context(@"a nested spec (context)", ^{ beforeEach(^{ // NSLog(@"=====================> I should run only before the nested specs."); }); afterEach(^{ // NSLog(@"=====================> I should run only after the nested specs."); }); it(@"should also run", ^{ // NSLog(@"=====================> Nested spec"); }); it(@"should also also run", ^{ // NSLog(@"=====================> Another nested spec"); }); }); it(@"should run", ^{ // NSLog(@"=====================> Spec"); }); it(@"should be pending", PENDING); it(@"should also be pending", nil); xit(@"should also be pending (xit)", ^{}); describe(@"described specs should be pending", PENDING); describe(@"described specs should also be pending", nil); xdescribe(@"xdescribed specs should be pending", ^{}); context(@"contexted specs should be pending", PENDING); context(@"contexted specs should also be pending", nil); xcontext(@"xcontexted specs should be pending", ^{}); describe(@"empty describe blocks should be pending", ^{}); context(@"empty context blocks should be pending", ^{}); }); describe(@"The spec failure exception", ^{ // it(@"should generate a spec failure", ^{ // [[CDRSpecFailure specFailureWithReason:@"'cuz"] raise]; // }); // // it(@"should throw exception", ^{ // [[NSException exceptionWithName:@"exception name" reason:@"exception reason" userInfo:nil] raise]; // }); }); describe(@"subjectAction", ^{ __block int value; subjectAction(^{ value = 5; }); beforeEach(^{ value = 100; }); it(@"should run after the beforeEach", ^{ value should equal(5); }); describe(@"in a nested describe block", ^{ beforeEach(^{ value = 200; }); it(@"should run after all the beforeEach blocks", ^{ value should equal(5); }); }); }); describe(@"Matchers", ^{ describe(@"equality", ^{ describe(@"with Objective-C types", ^{ __block NSNumber *expectedNumber; beforeEach(^{ expectedNumber = [NSNumber numberWithInt:1]; }); it(@"should succeed when the two objects are equal", ^{ expect(expectedNumber).to(equal([NSNumber numberWithInt:1])); }); it(@"should fail when the two objects are not equal", ^{ expectFailure(^{ expect(expectedNumber).to(equal([NSNumber numberWithInt:2])); }); }); }); describe(@"with built-in types", ^{ __block int expectedValue = 1; beforeEach(^{ expectedValue = 1; }); it(@"should succeed when the two objects are equal", ^{ expect(expectedValue).to(equal(1)); }); it(@"should succeed with different types that are comparable", ^{ expect(expectedValue).to(equal(1.0)); }); it(@"should fail when the objects are not equal", ^{ expectFailure(^{ expect(expectedValue).to(equal(2)); }); }); }); }); describe(@"that fail outside of an `it` block", ^{ __block NSException *caughtException = nil; @try { describe(@"performing the assertion", ^{ 1 should equal(2); }); } @catch (NSException *exception) { caughtException = [exception retain]; } it(@"should raise an exception with a helpful message", ^{ caughtException.name should equal(NSInternalInconsistencyException); caughtException.reason should contain(@"Caught a spec failure before the specs began to run. Did you forget to put your assertion into an `it` block?. The failure was:"); }); }); }); describe(@"a describe block", ^{ beforeEach(^{ globalValue__ = nil; }); describe(@"that contains a beforeEach in a shared example group", ^{ itShouldBehaveLike(@"a describe context that contains a beforeEach in a shared example group"); it(@"should not run the shared beforeEach before specs outside the shared example group", ^{ expect(globalValue__).to(be_nil()); }); }); describe(@"that passes a value to the shared example context", ^{ beforeEach(^{ globalValue__ = @"something"; [[CDRSpecHelper specHelper].sharedExampleContext setObject:globalValue__ forKey:@"value"]; }); itShouldBehaveLike(@"a shared example group that receives a value in the context"); }); describe(@"that passes a value in-line to the shared example context", ^{ beforeEach(^{ globalValue__ = @"something"; }); itShouldBehaveLike(@"a shared example group that receives a value in the context", ^(NSMutableDictionary *context) { context[@"value"] = globalValue__; }); }); itShouldBehaveLike(@"a shared example group that contains a failing spec"); }); describe(@"a describe block that tries to include a shared example group that doesn't exist", ^{ @try { itShouldBehaveLike(@"a unicorn"); } @catch (NSException *) { return; } [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Should have thrown an exception" userInfo:nil]; }); SPEC_END SHARED_EXAMPLE_GROUPS_BEGIN(Specs) sharedExamplesFor(@"a describe context that contains a beforeEach in a shared example group", ^(NSDictionary *context) { beforeEach(^{ expect([[CDRSpecHelper specHelper].sharedExampleContext count]).to(equal(0)); globalValue__ = [NSString string]; }); it(@"should run the shared beforeEach before specs inside the shared example group", ^{ expect(globalValue__).to_not(be_nil()); }); }); sharedExamplesFor(@"a shared example group that receives a value in the context", ^(NSDictionary *context) { it(@"should receive the values set in the global shared example context", ^{ expect([context objectForKey:@"value"]).to(equal(globalValue__)); }); }); sharedExamplesFor(@"a shared example group that contains a failing spec", ^(NSDictionary *context) { it(@"should fail in the expected fashion", ^{ expectFailure(^{ expect(@"wibble").to(equal(@"wobble")); }); }); }); SHARED_EXAMPLE_GROUPS_END ================================================ FILE: Spec/SpecSpec2.m ================================================ #import "CDRSpecHelper.h" SPEC_BEGIN(SpecSpec2) describe(@"A second spec file in the same target", ^{ it(@"should run", ^{ // NSLog(@"=====================> Spec 2"); }); }); SPEC_END ================================================ FILE: Spec/Support/ARCViewController.h ================================================ #import @interface AnotherARCViewController : UIViewController @end @interface ARCView : UIView @end @interface ARCObject : NSObject - (void)someMethod; @end @interface ARCViewController : UIViewController @property (weak, nonatomic) ARCView *weakSubview; @property (weak, nonatomic) AnotherARCViewController *weakChildController; @property (weak, nonatomic) UITextField *weakTextField; @property (weak, nonatomic) ARCObject *weakObject; @end ================================================ FILE: Spec/Support/ARCViewController.m ================================================ #import "ARCViewController.h" #if !__has_feature(objc_arc) #error This class must be compiled with ARC to work properly with the spec that uses it #endif @implementation ARCView @end @implementation AnotherARCViewController @end @implementation ARCObject - (void)someMethod { NSLog(@"================> %@", @"This should be stubbed."); } @end @interface ARCViewController () @property (strong, nonatomic) NSArray *objects; @end @implementation ARCViewController - (void)viewDidLoad { [super viewDidLoad]; ARCView *subview = [[ARCView alloc] init]; [self.view addSubview:subview]; self.weakSubview = subview; AnotherARCViewController *childController = [[AnotherARCViewController alloc] init]; [self addChildViewController:childController]; self.weakChildController = childController; UITextField *textField = [[UITextField alloc] init]; [self.view addSubview:textField]; self.weakTextField = textField; ARCObject *object = [[ARCObject alloc] init]; self.objects = @[object]; self.weakObject = object; } @end ================================================ FILE: Spec/Support/ArgumentReleaser.h ================================================ #import @interface ArgumentReleaser : NSObject - (void)releaseArgument:(id)arg; @end ================================================ FILE: Spec/Support/ArgumentReleaser.m ================================================ #import "ArgumentReleaser.h" @implementation ArgumentReleaser - (void)releaseArgument:(id)arg { [arg release]; } @end ================================================ FILE: Spec/Support/CedarObservedObject.h ================================================ #import @protocol CedarObservedObject - (void) mutateObservedProperty; @end ================================================ FILE: Spec/Support/CedarTestSpecBuilder.h ================================================ #import #import "Cedar.h" @interface CedarTestSpecBuilder : CDRSpec - (void)wrapWithDeclareBehaviors:(dispatch_block_t)block; @end ================================================ FILE: Spec/Support/CedarTestSpecBuilder.m ================================================ #import "CedarTestSpecBuilder.h" @interface CedarTestSpecBuilder () @property dispatch_block_t block; @end @implementation CedarTestSpecBuilder - (void)wrapWithDeclareBehaviors:(dispatch_block_t)block { self.block = block; } - (void)declareBehaviors { if (self.block) { self.block(); } } @end ================================================ FILE: Spec/Support/DeallocNotifier.h ================================================ #import @interface DeallocNotifier : NSObject - (instancetype)initWithNotificationBlock:(void (^)(void))block; @end ================================================ FILE: Spec/Support/DeallocNotifier.m ================================================ #import "DeallocNotifier.h" @interface DeallocNotifier () @property (nonatomic, copy) void (^notificationBlock)(void); @end @implementation DeallocNotifier - (instancetype)initWithNotificationBlock:(void (^)(void))block { if (self = [super init]) { self.notificationBlock = block; } return self; } - (void)dealloc { self.notificationBlock(); self.notificationBlock = (id)[NSNull null]; [super dealloc]; } @end ================================================ FILE: Spec/Support/ExampleWithPublicRunDates.h ================================================ #import #import "CDRExample.h" @interface ExampleWithPublicRunDates : CDRExample - (void)setStartDate:(NSDate *)startDate; - (void)setEndDate:(NSDate *)endDate; @end ================================================ FILE: Spec/Support/ExampleWithPublicRunDates.mm ================================================ #import "ExampleWithPublicRunDates.h" @implementation ExampleWithPublicRunDates - (void)setStartDate:(NSDate *)startDate { if (startDate_) { [startDate_ autorelease];}; startDate_ = [startDate retain]; } - (void)setEndDate:(NSDate *)endDate { if (endDate_) { [endDate_ autorelease];}; endDate_ = [endDate retain]; } @end ================================================ FILE: Spec/Support/FibonacciCalculator.h ================================================ #import @interface FibonacciCalculator : NSObject - (int)computeFibonnaciNumberVeryVerySlowly:(int)n; - (int)computeFibonnaciNumberVeryVeryQuickly:(int)n; @end ================================================ FILE: Spec/Support/FibonacciCalculator.m ================================================ #import "FibonacciCalculator.h" @implementation FibonacciCalculator - (int)computeFibonnaciNumberVeryVerySlowly:(int)n { if (n == 0) return 0; if (n == 1) return 1; return [self computeFibonnaciNumberVeryVerySlowly:n - 1] + [self computeFibonnaciNumberVeryVerySlowly:n - 2]; } - (int)computeFibonnaciNumberVeryVeryQuickly:(int)n { return (pow((1 + sqrt(5)) / 2.0, n) - pow((1 - sqrt(5)) / 2.0, n) ) / sqrt(5); } @end ================================================ FILE: Spec/Support/FooSuperclass.h ================================================ #import @protocol BazProtocol @end @interface FooSuperclass : NSObject @end @interface BarSubclass : FooSuperclass @end @interface QuuxSubclass : FooSuperclass @end ================================================ FILE: Spec/Support/FooSuperclass.m ================================================ #import "FooSuperclass.h" @implementation FooSuperclass @end @implementation BarSubclass @end @implementation QuuxSubclass @end ================================================ FILE: Spec/Support/GData/GDataXMLNode.h ================================================ /* Copyright (c) 2008 Google Inc. * * 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. */ // These node, element, and document classes implement a subset of the methods // provided by NSXML. While NSXML behavior is mimicked as much as possible, // there are important differences. // // The biggest difference is that, since this is based on libxml2, there // is no retain model for the underlying node data. Rather than copy every // node obtained from a parse tree (which would have a substantial memory // impact), we rely on weak references, and it is up to the code that // created a document to retain it for as long as any // references rely on nodes inside that document tree. #import // libxml includes require that the target Header Search Paths contain // // /usr/include/libxml2 // // and Other Linker Flags contain // // -lxml2 #import #import #import #import #import #ifdef GDATA_TARGET_NAMESPACE // we're using target namespace macros #import "GDataDefines.h" #endif #undef _EXTERN #undef _INITIALIZE_AS #ifdef GDATAXMLNODE_DEFINE_GLOBALS #define _EXTERN #define _INITIALIZE_AS(x) =x #else #if defined(__cplusplus) #define _EXTERN extern "C" #else #define _EXTERN extern #endif #define _INITIALIZE_AS(x) #endif // when no namespace dictionary is supplied for XPath, the default namespace // for the evaluated tree is registered with the prefix _def_ns _EXTERN const char* kGDataXMLXPathDefaultNamespacePrefix _INITIALIZE_AS("_def_ns"); // Nomenclature for method names: // // Node = GData node // XMLNode = xmlNodePtr // // So, for example: // + (id)nodeConsumingXMLNode:(xmlNodePtr)theXMLNode; @class NSArray, NSDictionary, NSError, NSString, NSURL; @class GDataXMLElement, GDataXMLDocument; enum { GDataXMLInvalidKind = 0, GDataXMLDocumentKind, GDataXMLElementKind, GDataXMLAttributeKind, GDataXMLNamespaceKind, GDataXMLProcessingInstructionKind, GDataXMLCommentKind, GDataXMLTextKind, GDataXMLDTDKind, GDataXMLEntityDeclarationKind, GDataXMLAttributeDeclarationKind, GDataXMLElementDeclarationKind, GDataXMLNotationDeclarationKind }; typedef NSUInteger GDataXMLNodeKind; @interface GDataXMLNode : NSObject { @protected // NSXMLNodes can have a namespace URI or prefix even if not part // of a tree; xmlNodes cannot. When we create nodes apart from // a tree, we'll store the dangling prefix or URI in the xmlNode's name, // like // "prefix:name" // or // "{http://uri}:name" // // We will fix up the node's namespace and name (and those of any children) // later when adding the node to a tree with addChild: or addAttribute:. // See fixUpNamespacesForNode:. xmlNodePtr xmlNode_; // may also be an xmlAttrPtr or xmlNsPtr BOOL shouldFreeXMLNode_; // if yes, xmlNode_ will be free'd in dealloc // cached values NSString *cachedName_; NSArray *cachedChildren_; NSArray *cachedAttributes_; } + (GDataXMLElement *)elementWithName:(NSString *)name; + (GDataXMLElement *)elementWithName:(NSString *)name stringValue:(NSString *)value; + (GDataXMLElement *)elementWithName:(NSString *)name URI:(NSString *)value; + (id)attributeWithName:(NSString *)name stringValue:(NSString *)value; + (id)attributeWithName:(NSString *)name URI:(NSString *)attributeURI stringValue:(NSString *)value; + (id)namespaceWithName:(NSString *)name stringValue:(NSString *)value; + (id)textWithStringValue:(NSString *)value; - (NSString *)stringValue; - (void)setStringValue:(NSString *)str; - (NSUInteger)childCount; - (NSArray *)children; - (GDataXMLNode *)childAtIndex:(unsigned)index; - (NSString *)localName; - (NSString *)name; - (NSString *)prefix; - (NSString *)URI; - (GDataXMLNodeKind)kind; - (NSString *)XMLString; + (NSString *)localNameForName:(NSString *)name; + (NSString *)prefixForName:(NSString *)name; // This is the preferred entry point for nodesForXPath. This takes an explicit // namespace dictionary (keys are prefixes, values are URIs). - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error; // This implementation of nodesForXPath registers namespaces only from the // document's root node. _def_ns may be used as a prefix for the default // namespace, though there's no guarantee that the default namespace will // be consistenly the same namespace in server responses. - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error; // access to the underlying libxml node; be sure to release the cached values // if you change the underlying tree at all - (xmlNodePtr)XMLNode; - (void)releaseCachedValues; @end @interface GDataXMLElement : GDataXMLNode - (id)initWithXMLString:(NSString *)str error:(NSError **)error; - (NSArray *)namespaces; - (void)setNamespaces:(NSArray *)namespaces; - (void)addNamespace:(GDataXMLNode *)aNamespace; // addChild adds a copy of the child node to the element - (void)addChild:(GDataXMLNode *)child; - (void)removeChild:(GDataXMLNode *)child; - (NSArray *)elementsForName:(NSString *)name; - (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI; - (NSArray *)attributes; - (GDataXMLNode *)attributeForName:(NSString *)name; - (GDataXMLNode *)attributeForLocalName:(NSString *)name URI:(NSString *)attributeURI; - (void)addAttribute:(GDataXMLNode *)attribute; - (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI; @end @interface GDataXMLDocument : NSObject { @protected xmlDoc* xmlDoc_; // strong; always free'd in dealloc } - (id)initWithXMLString:(NSString *)str options:(unsigned int)mask error:(NSError **)error; - (id)initWithData:(NSData *)data options:(unsigned int)mask error:(NSError **)error; // initWithRootElement uses a copy of the argument as the new document's root - (id)initWithRootElement:(GDataXMLElement *)element; - (GDataXMLElement *)rootElement; - (NSData *)XMLData; - (void)setVersion:(NSString *)version; - (void)setCharacterEncoding:(NSString *)encoding; // This is the preferred entry point for nodesForXPath. This takes an explicit // namespace dictionary (keys are prefixes, values are URIs). - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error; // This implementation of nodesForXPath registers namespaces only from the // document's root node. _def_ns may be used as a prefix for the default // namespace, though there's no guarantee that the default namespace will // be consistenly the same namespace in server responses. - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error; - (NSString *)description; @end ================================================ FILE: Spec/Support/GData/GDataXMLNode.m ================================================ /* Copyright (c) 2008 Google Inc. * * 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. */ #define GDATAXMLNODE_DEFINE_GLOBALS 1 #import "GDataXMLNode.h" @class NSArray, NSDictionary, NSError, NSString, NSURL; @class GDataXMLElement, GDataXMLDocument; static const int kGDataXMLParseOptions = (XML_PARSE_NOCDATA | XML_PARSE_NOBLANKS); // dictionary key callbacks for string cache static const void *StringCacheKeyRetainCallBack(CFAllocatorRef allocator, const void *str); static void StringCacheKeyReleaseCallBack(CFAllocatorRef allocator, const void *str); static CFStringRef StringCacheKeyCopyDescriptionCallBack(const void *str); static Boolean StringCacheKeyEqualCallBack(const void *str1, const void *str2); static CFHashCode StringCacheKeyHashCallBack(const void *str); // isEqual: has the fatal flaw that it doesn't deal well with the received // being nil. We'll use this utility instead. // Static copy of AreEqualOrBothNil from GDataObject.m, so that using // GDataXMLNode does not require pulling in all of GData. static BOOL AreEqualOrBothNilPrivate(id obj1, id obj2) { if (obj1 == obj2) { return YES; } if (obj1 && obj2) { return [obj1 isEqual:obj2]; } return NO; } // convert NSString* to xmlChar* // // the "Get" part implies that ownership remains with str static xmlChar* GDataGetXMLString(NSString *str) { xmlChar* result = (xmlChar *)[str UTF8String]; return result; } // Make a fake qualified name we use as local name internally in libxml // data structures when there's no actual namespace node available to point to // from an element or attribute node // // Returns an autoreleased NSString* static NSString *GDataFakeQNameForURIAndName(NSString *theURI, NSString *name) { NSString *localName = [GDataXMLNode localNameForName:name]; NSString *fakeQName = [NSString stringWithFormat:@"{%@}:%@", theURI, localName]; return fakeQName; } // libxml2 offers xmlSplitQName2, but that searches forwards. Since we may // be searching for a whole URI shoved in as a prefix, like // {http://foo}:name // we'll search for the prefix in backwards from the end of the qualified name // // returns a copy of qname as the local name if there's no prefix static xmlChar *SplitQNameReverse(const xmlChar *qname, xmlChar **prefix) { // search backwards for a colon int qnameLen = xmlStrlen(qname); for (int idx = qnameLen - 1; idx >= 0; idx--) { if (qname[idx] == ':') { // found the prefix; copy the prefix, if requested if (prefix != NULL) { if (idx > 0) { *prefix = xmlStrsub(qname, 0, idx); } else { *prefix = NULL; } } if (idx < qnameLen - 1) { // return a copy of the local name xmlChar *localName = xmlStrsub(qname, idx + 1, qnameLen - idx - 1); return localName; } else { return NULL; } } } // no colon found, so the qualified name is the local name xmlChar *qnameCopy = xmlStrdup(qname); return qnameCopy; } @interface GDataXMLNode (PrivateMethods) // consuming a node implies it will later be freed when the instance is // dealloc'd; borrowing it implies that ownership and disposal remain the // job of the supplier of the node + (id)nodeConsumingXMLNode:(xmlNodePtr)theXMLNode; - (id)initConsumingXMLNode:(xmlNodePtr)theXMLNode; + (id)nodeBorrowingXMLNode:(xmlNodePtr)theXMLNode; - (id)initBorrowingXMLNode:(xmlNodePtr)theXMLNode; // getters of the underlying node - (xmlNodePtr)XMLNode; - (xmlNodePtr)XMLNodeCopy; // search for an underlying attribute - (GDataXMLNode *)attributeForXMLNode:(xmlAttrPtr)theXMLNode; // return an NSString for an xmlChar*, using our strings cache in the // document - (NSString *)stringFromXMLString:(const xmlChar *)chars; // setter/getter of the dealloc flag for the underlying node - (BOOL)shouldFreeXMLNode; - (void)setShouldFreeXMLNode:(BOOL)flag; @end @interface GDataXMLElement (PrivateMethods) + (void)fixUpNamespacesForNode:(xmlNodePtr)nodeToFix graftingToTreeNode:(xmlNodePtr)graftPointNode; @end @implementation GDataXMLNode + (void)load { xmlInitParser(); } // Note on convenience methods for making stand-alone element and // attribute nodes: // // Since we're making a node from scratch, we don't // have any namespace info. So the namespace prefix, if // any, will just be slammed into the node name. // We'll rely on the -addChild method below to remove // the namespace prefix and replace it with a proper ns // pointer. + (GDataXMLElement *)elementWithName:(NSString *)name { xmlNodePtr theNewNode = xmlNewNode(NULL, // namespace GDataGetXMLString(name)); if (theNewNode) { // succeeded return [self nodeConsumingXMLNode:theNewNode]; } return nil; } + (GDataXMLElement *)elementWithName:(NSString *)name stringValue:(NSString *)value { xmlNodePtr theNewNode = xmlNewNode(NULL, // namespace GDataGetXMLString(name)); if (theNewNode) { xmlNodePtr textNode = xmlNewText(GDataGetXMLString(value)); if (textNode) { xmlNodePtr temp = xmlAddChild(theNewNode, textNode); if (temp) { // succeeded return [self nodeConsumingXMLNode:theNewNode]; } } // failed; free the node and any children xmlFreeNode(theNewNode); } return nil; } + (GDataXMLElement *)elementWithName:(NSString *)name URI:(NSString *)theURI { // since we don't know a prefix yet, shove in the whole URI; we'll look for // a proper namespace ptr later when addChild calls fixUpNamespacesForNode NSString *fakeQName = GDataFakeQNameForURIAndName(theURI, name); xmlNodePtr theNewNode = xmlNewNode(NULL, // namespace GDataGetXMLString(fakeQName)); if (theNewNode) { return [self nodeConsumingXMLNode:theNewNode]; } return nil; } + (id)attributeWithName:(NSString *)name stringValue:(NSString *)value { xmlChar *xmlName = GDataGetXMLString(name); xmlChar *xmlValue = GDataGetXMLString(value); xmlAttrPtr theNewAttr = xmlNewProp(NULL, // parent node for the attr xmlName, xmlValue); if (theNewAttr) { return [self nodeConsumingXMLNode:(xmlNodePtr) theNewAttr]; } return nil; } + (id)attributeWithName:(NSString *)name URI:(NSString *)attributeURI stringValue:(NSString *)value { // since we don't know a prefix yet, shove in the whole URI; we'll look for // a proper namespace ptr later when addChild calls fixUpNamespacesForNode NSString *fakeQName = GDataFakeQNameForURIAndName(attributeURI, name); xmlChar *xmlName = GDataGetXMLString(fakeQName); xmlChar *xmlValue = GDataGetXMLString(value); xmlAttrPtr theNewAttr = xmlNewProp(NULL, // parent node for the attr xmlName, xmlValue); if (theNewAttr) { return [self nodeConsumingXMLNode:(xmlNodePtr) theNewAttr]; } return nil; } + (id)textWithStringValue:(NSString *)value { xmlNodePtr theNewText = xmlNewText(GDataGetXMLString(value)); if (theNewText) { return [self nodeConsumingXMLNode:theNewText]; } return nil; } + (id)namespaceWithName:(NSString *)name stringValue:(NSString *)value { xmlChar *href = GDataGetXMLString(value); xmlChar *prefix; if ([name length] > 0) { prefix = GDataGetXMLString(name); } else { // default namespace is represented by a nil prefix prefix = nil; } xmlNsPtr theNewNs = xmlNewNs(NULL, // parent node href, prefix); if (theNewNs) { return [self nodeConsumingXMLNode:(xmlNodePtr) theNewNs]; } return nil; } + (id)nodeConsumingXMLNode:(xmlNodePtr)theXMLNode { Class theClass; if (theXMLNode->type == XML_ELEMENT_NODE) { theClass = [GDataXMLElement class]; } else { theClass = [GDataXMLNode class]; } return [[[theClass alloc] initConsumingXMLNode:theXMLNode] autorelease]; } - (id)initConsumingXMLNode:(xmlNodePtr)theXMLNode { self = [super init]; if (self) { xmlNode_ = theXMLNode; shouldFreeXMLNode_ = YES; } return self; } + (id)nodeBorrowingXMLNode:(xmlNodePtr)theXMLNode { Class theClass; if (theXMLNode->type == XML_ELEMENT_NODE) { theClass = [GDataXMLElement class]; } else { theClass = [GDataXMLNode class]; } return [[[theClass alloc] initBorrowingXMLNode:theXMLNode] autorelease]; } - (id)initBorrowingXMLNode:(xmlNodePtr)theXMLNode { self = [super init]; if (self) { xmlNode_ = theXMLNode; shouldFreeXMLNode_ = NO; } return self; } - (void)releaseCachedValues { [cachedName_ release]; cachedName_ = nil; [cachedChildren_ release]; cachedChildren_ = nil; [cachedAttributes_ release]; cachedAttributes_ = nil; } // convert xmlChar* to NSString* // // returns an autoreleased NSString*, from the current node's document strings // cache if possible - (NSString *)stringFromXMLString:(const xmlChar *)chars { #if DEBUG NSCAssert(chars != NULL, @"GDataXMLNode sees an unexpected empty string"); #endif if (chars == NULL) return nil; CFMutableDictionaryRef cacheDict = NULL; NSString *result = nil; if (xmlNode_ != NULL && (xmlNode_->type == XML_ELEMENT_NODE || xmlNode_->type == XML_ATTRIBUTE_NODE || xmlNode_->type == XML_TEXT_NODE)) { // there is no xmlDocPtr in XML_NAMESPACE_DECL nodes, // so we can't cache the text of those // look for a strings cache in the document // // the cache is in the document's user-defined _private field if (xmlNode_->doc != NULL) { cacheDict = xmlNode_->doc->_private; if (cacheDict) { // this document has a strings cache result = (NSString *) CFDictionaryGetValue(cacheDict, chars); if (result) { // we found the xmlChar string in the cache; return the previously // allocated NSString, rather than allocate a new one return result; } } } } // allocate a new NSString for this xmlChar* result = [NSString stringWithUTF8String:(const char *) chars]; if (cacheDict) { // save the string in the document's string cache CFDictionarySetValue(cacheDict, chars, result); } return result; } - (void)dealloc { if (xmlNode_ && shouldFreeXMLNode_) { xmlFreeNode(xmlNode_); xmlNode_ = NULL; } [self releaseCachedValues]; [super dealloc]; } #pragma mark - - (void)setStringValue:(NSString *)str { if (xmlNode_ != NULL && str != nil) { if (xmlNode_->type == XML_NAMESPACE_DECL) { // for a namespace node, the value is the namespace URI xmlNsPtr nsNode = (xmlNsPtr)xmlNode_; if (nsNode->href != NULL) xmlFree((char *)nsNode->href); nsNode->href = xmlStrdup(GDataGetXMLString(str)); } else { // attribute or element node // do we need to call xmlEncodeSpecialChars? xmlNodeSetContent(xmlNode_, GDataGetXMLString(str)); } } } - (NSString *)stringValue { NSString *str = nil; if (xmlNode_ != NULL) { if (xmlNode_->type == XML_NAMESPACE_DECL) { // for a namespace node, the value is the namespace URI xmlNsPtr nsNode = (xmlNsPtr)xmlNode_; str = [self stringFromXMLString:(nsNode->href)]; } else { // attribute or element node xmlChar* chars = xmlNodeGetContent(xmlNode_); if (chars) { str = [self stringFromXMLString:chars]; xmlFree(chars); } } } return str; } - (NSString *)XMLString { NSString *str = nil; if (xmlNode_ != NULL) { xmlBufferPtr buff = xmlBufferCreate(); if (buff) { xmlDocPtr doc = NULL; int level = 0; int format = 0; int result = xmlNodeDump(buff, doc, xmlNode_, level, format); if (result > -1) { str = [[[NSString alloc] initWithBytes:(xmlBufferContent(buff)) length:(NSUInteger)(xmlBufferLength(buff)) encoding:NSUTF8StringEncoding] autorelease]; } xmlBufferFree(buff); } } // remove leading and trailing whitespace NSCharacterSet *ws = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSString *trimmed = [str stringByTrimmingCharactersInSet:ws]; return trimmed; } - (NSString *)localName { NSString *str = nil; if (xmlNode_ != NULL) { str = [self stringFromXMLString:(xmlNode_->name)]; // if this is part of a detached subtree, str may have a prefix in it str = [[self class] localNameForName:str]; } return str; } - (NSString *)prefix { NSString *str = nil; if (xmlNode_ != NULL) { // the default namespace's prefix is an empty string, though libxml // represents it as NULL for ns->prefix str = @""; if (xmlNode_->ns != NULL && xmlNode_->ns->prefix != NULL) { str = [self stringFromXMLString:(xmlNode_->ns->prefix)]; } } return str; } - (NSString *)URI { NSString *str = nil; if (xmlNode_ != NULL) { if (xmlNode_->ns != NULL && xmlNode_->ns->href != NULL) { str = [self stringFromXMLString:(xmlNode_->ns->href)]; } } return str; } - (NSString *)qualifiedName { // internal utility NSString *str = nil; if (xmlNode_ != NULL) { if (xmlNode_->type == XML_NAMESPACE_DECL) { // name of a namespace node xmlNsPtr nsNode = (xmlNsPtr)xmlNode_; // null is the default namespace; one is the loneliest number if (nsNode->prefix == NULL) { str = @""; } else { str = [self stringFromXMLString:(nsNode->prefix)]; } } else if (xmlNode_->ns != NULL && xmlNode_->ns->prefix != NULL) { // name of a non-namespace node // has a prefix char *qname; if (asprintf(&qname, "%s:%s", (const char *)xmlNode_->ns->prefix, xmlNode_->name) != -1) { str = [self stringFromXMLString:(const xmlChar *)qname]; free(qname); } } else { // lacks a prefix str = [self stringFromXMLString:(xmlNode_->name)]; } } return str; } - (NSString *)name { if (cachedName_ != nil) { return cachedName_; } NSString *str = [self qualifiedName]; cachedName_ = [str retain]; return str; } + (NSString *)localNameForName:(NSString *)name { if (name != nil) { NSRange range = [name rangeOfString:@":"]; if (range.location != NSNotFound) { // found a colon if (range.location + 1 < [name length]) { NSString *localName = [name substringFromIndex:(range.location + 1)]; return localName; } } } return name; } + (NSString *)prefixForName:(NSString *)name { if (name != nil) { NSRange range = [name rangeOfString:@":"]; if (range.location != NSNotFound) { NSString *prefix = [name substringToIndex:(range.location)]; return prefix; } } return nil; } - (NSUInteger)childCount { if (cachedChildren_ != nil) { return [cachedChildren_ count]; } if (xmlNode_ != NULL) { unsigned int count = 0; xmlNodePtr currChild = xmlNode_->children; while (currChild != NULL) { ++count; currChild = currChild->next; } return count; } return 0; } - (NSArray *)children { if (cachedChildren_ != nil) { return cachedChildren_; } NSMutableArray *array = nil; if (xmlNode_ != NULL) { xmlNodePtr currChild = xmlNode_->children; while (currChild != NULL) { GDataXMLNode *node = [GDataXMLNode nodeBorrowingXMLNode:currChild]; if (array == nil) { array = [NSMutableArray arrayWithObject:node]; } else { [array addObject:node]; } currChild = currChild->next; } cachedChildren_ = [array retain]; } return array; } - (GDataXMLNode *)childAtIndex:(unsigned)index { NSArray *children = [self children]; if ([children count] > index) { return [children objectAtIndex:index]; } return nil; } - (GDataXMLNodeKind)kind { if (xmlNode_ != NULL) { xmlElementType nodeType = xmlNode_->type; switch (nodeType) { case XML_ELEMENT_NODE: return GDataXMLElementKind; case XML_ATTRIBUTE_NODE: return GDataXMLAttributeKind; case XML_TEXT_NODE: return GDataXMLTextKind; case XML_CDATA_SECTION_NODE: return GDataXMLTextKind; case XML_ENTITY_REF_NODE: return GDataXMLEntityDeclarationKind; case XML_ENTITY_NODE: return GDataXMLEntityDeclarationKind; case XML_PI_NODE: return GDataXMLProcessingInstructionKind; case XML_COMMENT_NODE: return GDataXMLCommentKind; case XML_DOCUMENT_NODE: return GDataXMLDocumentKind; case XML_DOCUMENT_TYPE_NODE: return GDataXMLDocumentKind; case XML_DOCUMENT_FRAG_NODE: return GDataXMLDocumentKind; case XML_NOTATION_NODE: return GDataXMLNotationDeclarationKind; case XML_HTML_DOCUMENT_NODE: return GDataXMLDocumentKind; case XML_DTD_NODE: return GDataXMLDTDKind; case XML_ELEMENT_DECL: return GDataXMLElementDeclarationKind; case XML_ATTRIBUTE_DECL: return GDataXMLAttributeDeclarationKind; case XML_ENTITY_DECL: return GDataXMLEntityDeclarationKind; case XML_NAMESPACE_DECL: return GDataXMLNamespaceKind; case XML_XINCLUDE_START: return GDataXMLProcessingInstructionKind; case XML_XINCLUDE_END: return GDataXMLProcessingInstructionKind; case XML_DOCB_DOCUMENT_NODE: return GDataXMLDocumentKind; } } return GDataXMLInvalidKind; } - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error { // call through with no explicit namespace dictionary; that will register the // root node's namespaces return [self nodesForXPath:xpath namespaces:nil error:error]; } - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error { NSMutableArray *array = nil; NSInteger errorCode = -1; NSDictionary *errorInfo = nil; // xmlXPathNewContext requires a doc for its context, but if our elements // are created from GDataXMLElement's initWithXMLString there may not be // a document. (We may later decide that we want to stuff the doc used // there into a GDataXMLDocument and retain it, but we don't do that now.) // // We'll temporarily make a document to use for the xpath context. xmlDocPtr tempDoc = NULL; xmlNodePtr topParent = NULL; if (xmlNode_->doc == NULL) { tempDoc = xmlNewDoc(NULL); if (tempDoc) { // find the topmost node of the current tree to make the root of // our temporary document topParent = xmlNode_; while (topParent->parent != NULL) { topParent = topParent->parent; } xmlDocSetRootElement(tempDoc, topParent); } } if (xmlNode_ != NULL && xmlNode_->doc != NULL) { xmlXPathContextPtr xpathCtx = xmlXPathNewContext(xmlNode_->doc); if (xpathCtx) { // anchor at our current node xpathCtx->node = xmlNode_; // if a namespace dictionary was provided, register its contents if (namespaces) { // the dictionary keys are prefixes; the values are URIs for (NSString *prefix in namespaces) { NSString *uri = [namespaces objectForKey:prefix]; xmlChar *prefixChars = (xmlChar *) [prefix UTF8String]; xmlChar *uriChars = (xmlChar *) [uri UTF8String]; int result = xmlXPathRegisterNs(xpathCtx, prefixChars, uriChars); if (result != 0) { #if DEBUG NSCAssert1(result == 0, @"GDataXMLNode XPath namespace %@ issue", prefix); #endif } } } else { // no namespace dictionary was provided // // register the namespaces of this node, if it's an element, or of // this node's root element, if it's a document xmlNodePtr nsNodePtr = xmlNode_; if (xmlNode_->type == XML_DOCUMENT_NODE) { nsNodePtr = xmlDocGetRootElement((xmlDocPtr) xmlNode_); } // step through the namespaces, if any, and register each with the // xpath context if (nsNodePtr != NULL) { for (xmlNsPtr nsPtr = nsNodePtr->ns; nsPtr != NULL; nsPtr = nsPtr->next) { // default namespace is nil in the tree, but there's no way to // register a default namespace, so we'll register a fake one, // _def_ns const xmlChar* prefix = nsPtr->prefix; if (prefix == NULL) { prefix = (xmlChar*) kGDataXMLXPathDefaultNamespacePrefix; } int result = xmlXPathRegisterNs(xpathCtx, prefix, nsPtr->href); if (result != 0) { #if DEBUG NSCAssert1(result == 0, @"GDataXMLNode XPath namespace %s issue", prefix); #endif } } } } // now evaluate the path xmlXPathObjectPtr xpathObj; xpathObj = xmlXPathEval(GDataGetXMLString(xpath), xpathCtx); if (xpathObj) { // we have some result from the search array = [NSMutableArray array]; xmlNodeSetPtr nodeSet = xpathObj->nodesetval; if (nodeSet) { // add each node in the result set to our array for (int index = 0; index < nodeSet->nodeNr; index++) { xmlNodePtr currNode = nodeSet->nodeTab[index]; GDataXMLNode *node = [GDataXMLNode nodeBorrowingXMLNode:currNode]; if (node) { [array addObject:node]; } } } xmlXPathFreeObject(xpathObj); } else { // provide an error for failed evaluation const char *msg = xpathCtx->lastError.str1; errorCode = xpathCtx->lastError.code; if (msg) { NSString *errStr = [NSString stringWithUTF8String:msg]; errorInfo = [NSDictionary dictionaryWithObject:errStr forKey:@"error"]; } } xmlXPathFreeContext(xpathCtx); } } else { // not a valid node for using XPath errorInfo = [NSDictionary dictionaryWithObject:@"invalid node" forKey:@"error"]; } if (array == nil && error != nil) { *error = [NSError errorWithDomain:@"com.google.GDataXML" code:errorCode userInfo:errorInfo]; } if (tempDoc != NULL) { xmlUnlinkNode(topParent); xmlSetTreeDoc(topParent, NULL); xmlFreeDoc(tempDoc); } return array; } - (NSString *)description { int nodeType = (xmlNode_ ? (int)xmlNode_->type : -1); return [NSString stringWithFormat:@"%@ %p: {type:%d name:%@ xml:\"%@\"}", [self class], self, nodeType, [self name], [self XMLString]]; } - (id)copyWithZone:(NSZone *)zone { xmlNodePtr nodeCopy = [self XMLNodeCopy]; if (nodeCopy != NULL) { return [[[self class] alloc] initConsumingXMLNode:nodeCopy]; } return nil; } - (BOOL)isEqual:(GDataXMLNode *)other { if (self == other) return YES; if (![other isKindOfClass:[GDataXMLNode class]]) return NO; return [self XMLNode] == [other XMLNode] || ([self kind] == [other kind] && AreEqualOrBothNilPrivate([self name], [other name]) && [[self children] count] == [[other children] count]); } - (NSUInteger)hash { return (NSUInteger) (void *) [GDataXMLNode class]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [super methodSignatureForSelector:selector]; } #pragma mark - - (xmlNodePtr)XMLNodeCopy { if (xmlNode_ != NULL) { // Note: libxml will create a new copy of namespace nodes (xmlNs records) // and attach them to this copy in order to keep namespaces within this // node subtree copy value. xmlNodePtr nodeCopy = xmlCopyNode(xmlNode_, 1); // 1 = recursive return nodeCopy; } return NULL; } - (xmlNodePtr)XMLNode { return xmlNode_; } - (BOOL)shouldFreeXMLNode { return shouldFreeXMLNode_; } - (void)setShouldFreeXMLNode:(BOOL)flag { shouldFreeXMLNode_ = flag; } @end @implementation GDataXMLElement - (id)initWithXMLString:(NSString *)str error:(NSError **)error { self = [super init]; if (self) { const char *utf8Str = [str UTF8String]; // NOTE: We are assuming a string length that fits into an int xmlDocPtr doc = xmlReadMemory(utf8Str, (int)strlen(utf8Str), NULL, // URL NULL, // encoding kGDataXMLParseOptions); if (doc == NULL) { if (error) { // TODO(grobbins) use xmlSetGenericErrorFunc to capture error } } else { // copy the root node from the doc xmlNodePtr root = xmlDocGetRootElement(doc); if (root) { xmlNode_ = xmlCopyNode(root, 1); // 1: recursive shouldFreeXMLNode_ = YES; } xmlFreeDoc(doc); } if (xmlNode_ == NULL) { // failure if (error) { *error = [NSError errorWithDomain:@"com.google.GDataXML" code:-1 userInfo:nil]; } [self release]; return nil; } } return self; } - (NSArray *)namespaces { NSMutableArray *array = nil; if (xmlNode_ != NULL && xmlNode_->nsDef != NULL) { xmlNsPtr currNS = xmlNode_->nsDef; while (currNS != NULL) { // add this prefix/URI to the list, unless it's the implicit xml prefix if (!xmlStrEqual(currNS->prefix, (const xmlChar *) "xml")) { GDataXMLNode *node = [GDataXMLNode nodeBorrowingXMLNode:(xmlNodePtr) currNS]; if (array == nil) { array = [NSMutableArray arrayWithObject:node]; } else { [array addObject:node]; } } currNS = currNS->next; } } return array; } - (void)setNamespaces:(NSArray *)namespaces { if (xmlNode_ != NULL) { [self releaseCachedValues]; // remove previous namespaces if (xmlNode_->nsDef) { xmlFreeNsList(xmlNode_->nsDef); xmlNode_->nsDef = NULL; } // add a namespace for each object in the array NSEnumerator *enumerator = [namespaces objectEnumerator]; GDataXMLNode *namespaceNode; while ((namespaceNode = [enumerator nextObject]) != nil) { xmlNsPtr ns = (xmlNsPtr) [namespaceNode XMLNode]; if (ns) { (void)xmlNewNs(xmlNode_, ns->href, ns->prefix); } } // we may need to fix this node's own name; the graft point is where // the namespace search starts, so that points to this node too [[self class] fixUpNamespacesForNode:xmlNode_ graftingToTreeNode:xmlNode_]; } } - (void)addNamespace:(GDataXMLNode *)aNamespace { if (xmlNode_ != NULL) { [self releaseCachedValues]; xmlNsPtr ns = (xmlNsPtr) [aNamespace XMLNode]; if (ns) { (void)xmlNewNs(xmlNode_, ns->href, ns->prefix); // we may need to fix this node's own name; the graft point is where // the namespace search starts, so that points to this node too [[self class] fixUpNamespacesForNode:xmlNode_ graftingToTreeNode:xmlNode_]; } } } - (void)addChild:(GDataXMLNode *)child { if ([child kind] == GDataXMLAttributeKind) { [self addAttribute:child]; return; } if (xmlNode_ != NULL) { [self releaseCachedValues]; xmlNodePtr childNodeCopy = [child XMLNodeCopy]; if (childNodeCopy) { xmlNodePtr resultNode = xmlAddChild(xmlNode_, childNodeCopy); if (resultNode == NULL) { // failed to add xmlFreeNode(childNodeCopy); } else { // added this child subtree successfully; see if it has // previously-unresolved namespace prefixes that can now be fixed up [[self class] fixUpNamespacesForNode:childNodeCopy graftingToTreeNode:xmlNode_]; } } } } - (void)removeChild:(GDataXMLNode *)child { // this is safe for attributes too if (xmlNode_ != NULL) { [self releaseCachedValues]; xmlNodePtr node = [child XMLNode]; xmlUnlinkNode(node); // if the child node was borrowing its xmlNodePtr, then we need to // explicitly free it, since there is probably no owning object that will // free it on dealloc if (![child shouldFreeXMLNode]) { xmlFreeNode(node); } } } - (NSArray *)elementsForName:(NSString *)name { NSString *desiredName = name; if (xmlNode_ != NULL) { NSString *prefix = [[self class] prefixForName:desiredName]; if (prefix) { xmlChar* desiredPrefix = GDataGetXMLString(prefix); xmlNsPtr foundNS = xmlSearchNs(xmlNode_->doc, xmlNode_, desiredPrefix); if (foundNS) { // we found a namespace; fall back on elementsForLocalName:URI: // to get the elements NSString *desiredURI = [self stringFromXMLString:(foundNS->href)]; NSString *localName = [[self class] localNameForName:desiredName]; NSArray *nsArray = [self elementsForLocalName:localName URI:desiredURI]; return nsArray; } } // no namespace found for the node's prefix; try an exact match // for the name argument, including any prefix NSMutableArray *array = nil; // walk our list of cached child nodes NSArray *children = [self children]; for (GDataXMLNode *child in children) { xmlNodePtr currNode = [child XMLNode]; // find all children which are elements with the desired name if (currNode->type == XML_ELEMENT_NODE) { NSString *qName = [child name]; if ([qName isEqual:name]) { if (array == nil) { array = [NSMutableArray arrayWithObject:child]; } else { [array addObject:child]; } } } } return array; } return nil; } - (NSArray *)elementsForLocalName:(NSString *)localName URI:(NSString *)URI { NSMutableArray *array = nil; if (xmlNode_ != NULL && xmlNode_->children != NULL) { xmlChar* desiredNSHref = GDataGetXMLString(URI); xmlChar* requestedLocalName = GDataGetXMLString(localName); xmlChar* expectedLocalName = requestedLocalName; // resolve the URI at the parent level, since usually children won't // have their own namespace definitions, and we don't want to try to // resolve it once for every child xmlNsPtr foundParentNS = xmlSearchNsByHref(xmlNode_->doc, xmlNode_, desiredNSHref); if (foundParentNS == NULL) { NSString *fakeQName = GDataFakeQNameForURIAndName(URI, localName); expectedLocalName = GDataGetXMLString(fakeQName); } NSArray *children = [self children]; for (GDataXMLNode *child in children) { xmlNodePtr currChildPtr = [child XMLNode]; // find all children which are elements with the desired name and // namespace, or with the prefixed name and a null namespace if (currChildPtr->type == XML_ELEMENT_NODE) { // normally, we can assume the resolution done for the parent will apply // to the child, as most children do not define their own namespaces xmlNsPtr childLocalNS = foundParentNS; xmlChar* childDesiredLocalName = expectedLocalName; if (currChildPtr->nsDef != NULL) { // this child has its own namespace definitons; do a fresh resolve // of the namespace starting from the child, and see if it differs // from the resolve done starting from the parent. If the resolve // finds a different namespace, then override the desired local // name just for this child. childLocalNS = xmlSearchNsByHref(xmlNode_->doc, currChildPtr, desiredNSHref); if (childLocalNS != foundParentNS) { // this child does indeed have a different namespace resolution // result than was found for its parent if (childLocalNS == NULL) { // no namespace found NSString *fakeQName = GDataFakeQNameForURIAndName(URI, localName); childDesiredLocalName = GDataGetXMLString(fakeQName); } else { // a namespace was found; use the original local name requested, // not a faked one expected from resolving the parent childDesiredLocalName = requestedLocalName; } } } // check if this child's namespace and local name are what we're // seeking if (currChildPtr->ns == childLocalNS && currChildPtr->name != NULL && xmlStrEqual(currChildPtr->name, childDesiredLocalName)) { if (array == nil) { array = [NSMutableArray arrayWithObject:child]; } else { [array addObject:child]; } } } } // we return nil, not an empty array, according to docs } return array; } - (NSArray *)attributes { if (cachedAttributes_ != nil) { return cachedAttributes_; } NSMutableArray *array = nil; if (xmlNode_ != NULL && xmlNode_->properties != NULL) { xmlAttrPtr prop = xmlNode_->properties; while (prop != NULL) { GDataXMLNode *node = [GDataXMLNode nodeBorrowingXMLNode:(xmlNodePtr) prop]; if (array == nil) { array = [NSMutableArray arrayWithObject:node]; } else { [array addObject:node]; } prop = prop->next; } cachedAttributes_ = [array retain]; } return array; } - (void)addAttribute:(GDataXMLNode *)attribute { if (xmlNode_ != NULL) { [self releaseCachedValues]; xmlAttrPtr attrPtr = (xmlAttrPtr) [attribute XMLNode]; if (attrPtr) { // ignore this if an attribute with the name is already present, // similar to NSXMLNode's addAttribute xmlAttrPtr oldAttr; if (attrPtr->ns == NULL) { oldAttr = xmlHasProp(xmlNode_, attrPtr->name); } else { oldAttr = xmlHasNsProp(xmlNode_, attrPtr->name, attrPtr->ns->href); } if (oldAttr == NULL) { xmlNsPtr newPropNS = NULL; // if this attribute has a namespace, search for a matching namespace // on the node we're adding to if (attrPtr->ns != NULL) { newPropNS = xmlSearchNsByHref(xmlNode_->doc, xmlNode_, attrPtr->ns->href); if (newPropNS == NULL) { // make a new namespace on the parent node, and use that for the // new attribute newPropNS = xmlNewNs(xmlNode_, attrPtr->ns->href, attrPtr->ns->prefix); } } // copy the attribute onto this node xmlChar *value = xmlNodeGetContent((xmlNodePtr) attrPtr); xmlAttrPtr newProp = xmlNewNsProp(xmlNode_, newPropNS, attrPtr->name, value); if (newProp != NULL) { // we made the property, so clean up the property's namespace [[self class] fixUpNamespacesForNode:(xmlNodePtr)newProp graftingToTreeNode:xmlNode_]; } if (value != NULL) { xmlFree(value); } } } } } - (GDataXMLNode *)attributeForXMLNode:(xmlAttrPtr)theXMLNode { // search the cached attributes list for the GDataXMLNode with // the underlying xmlAttrPtr NSArray *attributes = [self attributes]; for (GDataXMLNode *attr in attributes) { if (theXMLNode == (xmlAttrPtr) [attr XMLNode]) { return attr; } } return nil; } - (GDataXMLNode *)attributeForName:(NSString *)name { if (xmlNode_ != NULL) { xmlAttrPtr attrPtr = xmlHasProp(xmlNode_, GDataGetXMLString(name)); if (attrPtr == NULL) { // can we guarantee that xmlAttrPtrs always have the ns ptr and never // a namespace as part of the actual attribute name? // split the name and its prefix, if any xmlNsPtr ns = NULL; NSString *prefix = [[self class] prefixForName:name]; if (prefix) { // find the namespace for this prefix, and search on its URI to find // the xmlNsPtr name = [[self class] localNameForName:name]; ns = xmlSearchNs(xmlNode_->doc, xmlNode_, GDataGetXMLString(prefix)); } const xmlChar* nsURI = ((ns != NULL) ? ns->href : NULL); attrPtr = xmlHasNsProp(xmlNode_, GDataGetXMLString(name), nsURI); } if (attrPtr) { GDataXMLNode *attr = [self attributeForXMLNode:attrPtr]; return attr; } } return nil; } - (GDataXMLNode *)attributeForLocalName:(NSString *)localName URI:(NSString *)attributeURI { if (xmlNode_ != NULL) { const xmlChar* name = GDataGetXMLString(localName); const xmlChar* nsURI = GDataGetXMLString(attributeURI); xmlAttrPtr attrPtr = xmlHasNsProp(xmlNode_, name, nsURI); if (attrPtr == NULL) { // if the attribute is in a tree lacking the proper namespace, // the local name may include the full URI as a prefix NSString *fakeQName = GDataFakeQNameForURIAndName(attributeURI, localName); const xmlChar* xmlFakeQName = GDataGetXMLString(fakeQName); attrPtr = xmlHasProp(xmlNode_, xmlFakeQName); } if (attrPtr) { GDataXMLNode *attr = [self attributeForXMLNode:attrPtr]; return attr; } } return nil; } - (NSString *)resolvePrefixForNamespaceURI:(NSString *)namespaceURI { if (xmlNode_ != NULL) { xmlChar* desiredNSHref = GDataGetXMLString(namespaceURI); xmlNsPtr foundNS = xmlSearchNsByHref(xmlNode_->doc, xmlNode_, desiredNSHref); if (foundNS) { // we found the namespace if (foundNS->prefix != NULL) { NSString *prefix = [self stringFromXMLString:(foundNS->prefix)]; return prefix; } else { // empty prefix is default namespace return @""; } } } return nil; } #pragma mark Namespace fixup routines + (void)deleteNamespacePtr:(xmlNsPtr)namespaceToDelete fromXMLNode:(xmlNodePtr)node { // utilty routine to remove a namespace pointer from an element's // namespace definition list. This is just removing the nsPtr // from the singly-linked list, the node's namespace definitions. xmlNsPtr currNS = node->nsDef; xmlNsPtr prevNS = NULL; while (currNS != NULL) { xmlNsPtr nextNS = currNS->next; if (namespaceToDelete == currNS) { // found it; delete it from the head of the node's ns definition list // or from the next field of the previous namespace if (prevNS != NULL) prevNS->next = nextNS; else node->nsDef = nextNS; xmlFreeNs(currNS); return; } prevNS = currNS; currNS = nextNS; } } + (void)fixQualifiedNamesForNode:(xmlNodePtr)nodeToFix graftingToTreeNode:(xmlNodePtr)graftPointNode { // Replace prefix-in-name with proper namespace pointers // // This is an inner routine for fixUpNamespacesForNode: // // see if this node's name lacks a namespace and is qualified, and if so, // see if we can resolve the prefix against the parent // // The prefix may either be normal, "gd:foo", or a URI // "{http://blah.com/}:foo" if (nodeToFix->ns == NULL) { xmlNsPtr foundNS = NULL; xmlChar* prefix = NULL; xmlChar* localName = SplitQNameReverse(nodeToFix->name, &prefix); if (localName != NULL) { if (prefix != NULL) { // if the prefix is wrapped by { and } then it's a URI int prefixLen = xmlStrlen(prefix); if (prefixLen > 2 && prefix[0] == '{' && prefix[prefixLen - 1] == '}') { // search for the namespace by URI xmlChar* uri = xmlStrsub(prefix, 1, prefixLen - 2); if (uri != NULL) { foundNS = xmlSearchNsByHref(graftPointNode->doc, graftPointNode, uri); xmlFree(uri); } } } if (foundNS == NULL) { // search for the namespace by prefix, even if the prefix is nil // (nil prefix means to search for the default namespace) foundNS = xmlSearchNs(graftPointNode->doc, graftPointNode, prefix); } if (foundNS != NULL) { // we found a namespace, so fix the ns pointer and the local name xmlSetNs(nodeToFix, foundNS); xmlNodeSetName(nodeToFix, localName); } if (prefix != NULL) { xmlFree(prefix); prefix = NULL; } xmlFree(localName); } } } + (void)fixDuplicateNamespacesForNode:(xmlNodePtr)nodeToFix graftingToTreeNode:(xmlNodePtr)graftPointNode namespaceSubstitutionMap:(NSMutableDictionary *)nsMap { // Duplicate namespace removal // // This is an inner routine for fixUpNamespacesForNode: // // If any of this node's namespaces are already defined at the graft point // level, add that namespace to the map of namespace substitutions // so it will be replaced in the children below the nodeToFix, and // delete the namespace record if (nodeToFix->type == XML_ELEMENT_NODE) { // step through the namespaces defined on this node xmlNsPtr definedNS = nodeToFix->nsDef; while (definedNS != NULL) { // see if this namespace is already defined higher in the tree, // with both the same URI and the same prefix; if so, add a mapping for // it xmlNsPtr foundNS = xmlSearchNsByHref(graftPointNode->doc, graftPointNode, definedNS->href); if (foundNS != NULL && foundNS != definedNS && xmlStrEqual(definedNS->prefix, foundNS->prefix)) { // store a mapping from this defined nsPtr to the one found higher // in the tree [nsMap setObject:[NSValue valueWithPointer:foundNS] forKey:[NSValue valueWithPointer:definedNS]]; // remove this namespace from the ns definition list of this node; // all child elements and attributes referencing this namespace // now have a dangling pointer and must be updated (that is done later // in this method) // // before we delete this namespace, move our pointer to the // next one xmlNsPtr nsToDelete = definedNS; definedNS = definedNS->next; [self deleteNamespacePtr:nsToDelete fromXMLNode:nodeToFix]; } else { // this namespace wasn't a duplicate; move to the next definedNS = definedNS->next; } } } // if this node's namespace is one we deleted, update it to point // to someplace better if (nodeToFix->ns != NULL) { NSValue *currNS = [NSValue valueWithPointer:nodeToFix->ns]; NSValue *replacementNS = [nsMap objectForKey:currNS]; if (replacementNS != nil) { xmlNsPtr replaceNSPtr = (xmlNsPtr)[replacementNS pointerValue]; xmlSetNs(nodeToFix, replaceNSPtr); } } } + (void)fixUpNamespacesForNode:(xmlNodePtr)nodeToFix graftingToTreeNode:(xmlNodePtr)graftPointNode namespaceSubstitutionMap:(NSMutableDictionary *)nsMap { // This is the inner routine for fixUpNamespacesForNode:graftingToTreeNode: // // This routine fixes two issues: // // Because we can create nodes with qualified names before adding // them to the tree that declares the namespace for the prefix, // we need to set the node namespaces after adding them to the tree. // // Because libxml adds namespaces to nodes when it copies them, // we want to remove redundant namespaces after adding them to // a tree. // // If only the Mac's libxml had xmlDOMWrapReconcileNamespaces, it could do // namespace cleanup for us // We only care about fixing names of elements and attributes if (nodeToFix->type != XML_ELEMENT_NODE && nodeToFix->type != XML_ATTRIBUTE_NODE) return; // Do the fixes [self fixQualifiedNamesForNode:nodeToFix graftingToTreeNode:graftPointNode]; [self fixDuplicateNamespacesForNode:nodeToFix graftingToTreeNode:graftPointNode namespaceSubstitutionMap:nsMap]; if (nodeToFix->type == XML_ELEMENT_NODE) { // when fixing element nodes, recurse for each child element and // for each attribute xmlNodePtr currChild = nodeToFix->children; while (currChild != NULL) { [self fixUpNamespacesForNode:currChild graftingToTreeNode:graftPointNode namespaceSubstitutionMap:nsMap]; currChild = currChild->next; } xmlAttrPtr currProp = nodeToFix->properties; while (currProp != NULL) { [self fixUpNamespacesForNode:(xmlNodePtr)currProp graftingToTreeNode:graftPointNode namespaceSubstitutionMap:nsMap]; currProp = currProp->next; } } } + (void)fixUpNamespacesForNode:(xmlNodePtr)nodeToFix graftingToTreeNode:(xmlNodePtr)graftPointNode { // allocate the namespace map that will be passed // down on recursive calls NSMutableDictionary *nsMap = [NSMutableDictionary dictionary]; [self fixUpNamespacesForNode:nodeToFix graftingToTreeNode:graftPointNode namespaceSubstitutionMap:nsMap]; } @end @interface GDataXMLDocument (PrivateMethods) - (void)addStringsCacheToDoc; @end @implementation GDataXMLDocument - (id)initWithXMLString:(NSString *)str options:(unsigned int)mask error:(NSError **)error { NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; GDataXMLDocument *doc = [self initWithData:data options:mask error:error]; return doc; } - (id)initWithData:(NSData *)data options:(unsigned int)mask error:(NSError **)error { self = [super init]; if (self) { const char *baseURL = NULL; const char *encoding = NULL; // NOTE: We are assuming [data length] fits into an int. xmlDoc_ = xmlReadMemory((const char*)[data bytes], (int)[data length], baseURL, encoding, kGDataXMLParseOptions); // TODO(grobbins) map option values if (xmlDoc_ == NULL) { if (error) { *error = [NSError errorWithDomain:@"com.google.GDataXML" code:-1 userInfo:nil]; // TODO(grobbins) use xmlSetGenericErrorFunc to capture error } [self release]; return nil; } else { if (error) *error = NULL; [self addStringsCacheToDoc]; } } return self; } - (id)initWithRootElement:(GDataXMLElement *)element { self = [super init]; if (self) { xmlDoc_ = xmlNewDoc(NULL); (void) xmlDocSetRootElement(xmlDoc_, [element XMLNodeCopy]); [self addStringsCacheToDoc]; } return self; } - (void)addStringsCacheToDoc { // utility routine for init methods #if DEBUG NSCAssert(xmlDoc_ != NULL && xmlDoc_->_private == NULL, @"GDataXMLDocument cache creation problem"); #endif // add a strings cache as private data for the document // // we'll use plain C pointers (xmlChar*) as the keys, and NSStrings // as the values CFIndex capacity = 0; // no limit CFDictionaryKeyCallBacks keyCallBacks = { 0, // version StringCacheKeyRetainCallBack, StringCacheKeyReleaseCallBack, StringCacheKeyCopyDescriptionCallBack, StringCacheKeyEqualCallBack, StringCacheKeyHashCallBack }; CFMutableDictionaryRef dict = CFDictionaryCreateMutable( kCFAllocatorDefault, capacity, &keyCallBacks, &kCFTypeDictionaryValueCallBacks); // we'll use the user-defined _private field for our cache xmlDoc_->_private = dict; } - (NSString *)description { return [NSString stringWithFormat:@"%@ %p", [self class], self]; } - (void)dealloc { if (xmlDoc_ != NULL) { // release the strings cache // // since it's a CF object, were anyone to use this in a GC environment, // this would need to be released in a finalize method, too if (xmlDoc_->_private != NULL) { CFRelease(xmlDoc_->_private); } xmlFreeDoc(xmlDoc_); } [super dealloc]; } #pragma mark - - (GDataXMLElement *)rootElement { GDataXMLElement *element = nil; if (xmlDoc_ != NULL) { xmlNodePtr rootNode = xmlDocGetRootElement(xmlDoc_); if (rootNode) { element = [GDataXMLElement nodeBorrowingXMLNode:rootNode]; } } return element; } - (NSData *)XMLData { if (xmlDoc_ != NULL) { xmlChar *buffer = NULL; int bufferSize = 0; xmlDocDumpMemory(xmlDoc_, &buffer, &bufferSize); if (buffer) { NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)bufferSize]; xmlFree(buffer); return data; } } return nil; } - (void)setVersion:(NSString *)version { if (xmlDoc_ != NULL) { if (xmlDoc_->version != NULL) { // version is a const char* so we must cast xmlFree((char *) xmlDoc_->version); xmlDoc_->version = NULL; } if (version != nil) { xmlDoc_->version = xmlStrdup(GDataGetXMLString(version)); } } } - (void)setCharacterEncoding:(NSString *)encoding { if (xmlDoc_ != NULL) { if (xmlDoc_->encoding != NULL) { // version is a const char* so we must cast xmlFree((char *) xmlDoc_->encoding); xmlDoc_->encoding = NULL; } if (encoding != nil) { xmlDoc_->encoding = xmlStrdup(GDataGetXMLString(encoding)); } } } - (NSArray *)nodesForXPath:(NSString *)xpath error:(NSError **)error { return [self nodesForXPath:xpath namespaces:nil error:error]; } - (NSArray *)nodesForXPath:(NSString *)xpath namespaces:(NSDictionary *)namespaces error:(NSError **)error { if (xmlDoc_ != NULL) { GDataXMLNode *docNode = [GDataXMLElement nodeBorrowingXMLNode:(xmlNodePtr)xmlDoc_]; NSArray *array = [docNode nodesForXPath:xpath namespaces:namespaces error:error]; return array; } return nil; } @end // // Dictionary key callbacks for our C-string to NSString cache dictionary // static const void *StringCacheKeyRetainCallBack(CFAllocatorRef allocator, const void *str) { // copy the key xmlChar* key = xmlStrdup(str); return key; } static void StringCacheKeyReleaseCallBack(CFAllocatorRef allocator, const void *str) { // free the key char *chars = (char *)str; xmlFree((char *) chars); } static CFStringRef StringCacheKeyCopyDescriptionCallBack(const void *str) { // make a CFString from the key CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)str, kCFStringEncodingUTF8); return cfStr; } static Boolean StringCacheKeyEqualCallBack(const void *str1, const void *str2) { // compare the key strings if (str1 == str2) return true; int result = xmlStrcmp(str1, str2); return (result == 0); } static CFHashCode StringCacheKeyHashCallBack(const void *str) { // dhb hash, per http://www.cse.yorku.ca/~oz/hash.html CFHashCode hash = 5381; unsigned int c; const unsigned char *chars = (const unsigned char *)str; while ((c = *chars++) != 0) { hash = ((hash << 5) + hash) + c; } return hash; } ================================================ FILE: Spec/Support/ObjectWithCollections.h ================================================ #import #import "CedarObservedObject.h" @interface ObjectWithCollections : NSObject @property (retain, nonatomic) NSMutableArray *array; @property (retain, nonatomic) NSMutableSet *set; @property (retain, nonatomic) NSMutableOrderedSet *orderedSet; @property (retain, nonatomic) NSMutableArray *manualArray; @property (retain, nonatomic) NSMutableSet *manualSet; @end ================================================ FILE: Spec/Support/ObjectWithCollections.m ================================================ #import "ObjectWithCollections.h" @implementation ObjectWithCollections - (instancetype)init { if (self = [super init]) { self.array = [NSMutableArray array]; self.set = [NSMutableSet set]; self.orderedSet = [NSMutableOrderedSet orderedSet]; self.manualArray = [NSMutableArray array]; self.manualSet = [NSMutableSet set]; } return self; } - (void)dealloc { self.array = nil; self.set = nil; self.orderedSet = nil; self.manualArray = nil; self.manualSet = nil; [super dealloc]; } + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { BOOL automatic; if ([key isEqualToString:@"manualArray"]) { automatic = NO; } else { automatic = [super automaticallyNotifiesObserversForKey:key]; } return automatic; } - (void) mutateObservedProperty { [[self mutableArrayValueForKey:@"array"] addObject:@"mutations are cool"]; [[self mutableSetValueForKey:@"set"] addObject:@"mutations are cool"]; [[self mutableOrderedSetValueForKey:@"orderedSet"] addObject:@"mutations are cool"]; [[self mutableArrayValueForKeyPath:@"array"] addObject:@"jinkies!"]; [[self mutableSetValueForKeyPath:@"set"] addObject:@"mutate all the key paths"]; [[self mutableOrderedSetValueForKeyPath:@"orderedSet"] addObject:@"in your tests, mutating your sets"]; NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:0]; [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:@"manualArray"]; [self.manualArray addObject:@"testing all the things"]; [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:@"manualArray"]; NSSet *changeObjects = [NSSet setWithObjects:@"testing all the things", nil]; [self willChangeValueForKey:@"manualSet" withSetMutation:NSKeyValueSetSetMutation usingObjects:changeObjects]; [self.manualSet addObject:[[changeObjects allObjects] objectAtIndex:0]]; [self didChangeValueForKey:@"manualSet" withSetMutation:NSKeyValueSetSetMutation usingObjects:changeObjects]; } @end ================================================ FILE: Spec/Support/ObjectWithForwardingTarget.h ================================================ #import @interface ObjectWithForwardingTarget : NSObject - (id)initWithNumberOfThings:(NSUInteger)count; - (void)updateWithValue:(NSUInteger)value; @end @interface ObjectWithForwardingTarget (Forwarded) - (NSUInteger)count; - (void)unforwardedUnimplementedMethod; @end ================================================ FILE: Spec/Support/ObjectWithForwardingTarget.m ================================================ #import "ObjectWithForwardingTarget.h" @interface ObjectWithForwardingTarget () @property (nonatomic, retain) NSArray *things; @end @implementation ObjectWithForwardingTarget - (id)initWithNumberOfThings:(NSUInteger)count { self = [super init]; if (self) { NSMutableArray *mutableThings = [NSMutableArray arrayWithCapacity:count]; for (NSUInteger i = 0; i < count; i++) { [mutableThings addObject:[[[NSObject alloc] init] autorelease]]; } self.things = [NSArray arrayWithArray:mutableThings]; } return self; } - (void)dealloc { self.things = nil; [super dealloc]; } - (BOOL)respondsToSelector:(SEL)aSelector { return [super respondsToSelector:aSelector] || [self.things respondsToSelector:aSelector] || aSelector == @selector(unforwardedUnimplementedMethod); } + (BOOL)instancesRespondToSelector:(SEL)aSelector { return [super instancesRespondToSelector:aSelector] || [[NSArray class] instancesRespondToSelector:aSelector] || aSelector == @selector(unforwardedUnimplementedMethod); } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { NSMethodSignature *ownSignature = [super methodSignatureForSelector:aSelector]; return ownSignature ? ownSignature : [self.things methodSignatureForSelector:aSelector]; } + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector { NSMethodSignature *ownSignature = [super instanceMethodSignatureForSelector:aSelector]; return ownSignature ? ownSignature : [[NSArray class] instanceMethodSignatureForSelector:aSelector]; } - (id)forwardingTargetForSelector:(SEL)aSelector { return [self.things respondsToSelector:aSelector] ? self.things : [super forwardingTargetForSelector:aSelector]; } - (void)updateWithValue:(NSUInteger)value { } @end ================================================ FILE: Spec/Support/ObjectWithProperty.h ================================================ #import #import #import "CedarObservedObject.h" @interface ObjectWithProperty : NSObject @property (nonatomic, assign) CGFloat floatProperty; @property (nonatomic, assign) CGFloat manualFloatProperty; @end ================================================ FILE: Spec/Support/ObjectWithProperty.m ================================================ #import "ObjectWithProperty.h" @implementation ObjectWithProperty + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { BOOL automatic; if ([key isEqualToString:@"manualFloatProperty"]) { automatic = NO; } else { automatic = [super automaticallyNotifiesObserversForKey:key]; } return automatic; } - (void) mutateObservedProperty { self.floatProperty = 12; [self willChangeValueForKey:@"manualFloatProperty"]; self.manualFloatProperty = 21; [self didChangeValueForKey:@"manualFloatProperty"]; } @end ================================================ FILE: Spec/Support/ObjectWithValueEquality.h ================================================ #import @interface ObjectWithValueEquality : NSObject - (instancetype)initWithInteger:(NSInteger)integer; @end ================================================ FILE: Spec/Support/ObjectWithValueEquality.m ================================================ #import "ObjectWithValueEquality.h" @implementation ObjectWithValueEquality { NSInteger _integer; } - (instancetype)initWithInteger:(NSInteger)integer { if (self = [super init]) { _integer = integer; } return self; } - (BOOL)isEqual:(id)object { return [object isKindOfClass:[ObjectWithValueEquality class]] && ((ObjectWithValueEquality *)object)->_integer == _integer; } - (NSUInteger)hash { return [@(_integer) hash]; } @end ================================================ FILE: Spec/Support/ObjectWithWeakDelegate.h ================================================ #import @protocol ExampleDelegate - (void)someMessage; @end @interface ObjectWithWeakDelegate : NSObject @property (weak, nonatomic) id delegate; - (void)tellTheDelegate; @end ================================================ FILE: Spec/Support/ObjectWithWeakDelegate.m ================================================ #import "ObjectWithWeakDelegate.h" #if !__has_feature(objc_arc) #error This class must be compiled with ARC to work properly with the spec that uses it #endif @implementation ObjectWithWeakDelegate - (void)tellTheDelegate { [self.delegate someMessage]; } @end ================================================ FILE: Spec/Support/SimpleIncrementer.h ================================================ #import typedef struct { size_t a, b, c, d; } LargeIncrementerStruct; typedef LargeIncrementerStruct (^ComplexIncrementerBlock)(NSNumber *, LargeIncrementerStruct, id); @class FooSuperclass; @protocol InheritedProtocol @end @protocol SimpleIncrementer @required - (size_t)value; - (size_t)aVeryLargeNumber; - (NSNumber *)valueAsNumber; - (void)increment; - (void)incrementBy:(size_t)amount; - (void)incrementByNumber:(NSNumber *)number; - (void)incrementByInteger:(NSUInteger)number; - (void)incrementByABit:(unsigned int)aBit andABitMore:(NSNumber *)aBitMore; - (void)incrementWithException; - (void)methodWithBlock:(void(^)())blockArgument; - (void)methodWithCString:(char *)string; - (id)methodWithInheritedProtocol:(id)protocol; - (NSString *)methodWithString:(NSString *)string; - (NSNumber *)methodWithNumber1:(NSNumber *)arg1 andNumber2:(NSNumber *)arg2; - (double)methodWithDouble1:(double)double1 andDouble2:(double)double2; - (LargeIncrementerStruct)methodWithLargeStruct1:(LargeIncrementerStruct)struct1 andLargeStruct2:(LargeIncrementerStruct)struct2; - (void)methodWithNumber:(NSNumber *)number complexBlock:(ComplexIncrementerBlock)block; - (NSString *)methodWithFooSuperclass:(FooSuperclass *)fooInstance; - (void)methodWithPrimitivePointerArgument:(int *)arg; - (void)methodWithObjectPointerArgument:(out id *)anObjectPointer; @optional - (size_t)whatIfIIncrementedBy:(size_t)amount; @end @interface IncrementerBase : NSObject @end @interface SimpleIncrementer : IncrementerBase @property (nonatomic, copy) NSString *string; @end ================================================ FILE: Spec/Support/SimpleIncrementer.m ================================================ #import "SimpleIncrementer.h" @interface SimpleIncrementer () @property (nonatomic, assign) size_t value; @end @implementation IncrementerBase @end @implementation SimpleIncrementer @synthesize value = value_; - (void)increment { ++self.value; } - (size_t)aVeryLargeNumber { return 0x7fffffff; } - (NSNumber *)valueAsNumber { return @(self.value); } - (void)incrementBy:(size_t)amount { self.value += amount; } - (void)incrementByNumber:(NSNumber *)number { self.value += [number intValue]; } - (void)incrementByInteger:(NSUInteger)integer { self.value += integer; } - (void)incrementByABit:(unsigned int)aBit andABitMore:(NSNumber *)aBitMore { self.value += aBit + [aBitMore intValue]; } - (void)incrementWithException { [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"wibble" userInfo:nil] raise]; } - (void)methodWithBlock:(void(^)())blockArgument { } - (void)methodWithCString:(char *)string { } - (id)methodWithInheritedProtocol:(id)protocol { return @1; } - (NSString *)methodWithString:(NSString *)string { return string; } - (NSNumber *)methodWithNumber1:(NSNumber *)arg1 andNumber2:(NSNumber *)arg2 { return @([arg1 floatValue] * [arg2 floatValue]); } - (double)methodWithDouble1:(double)double1 andDouble2:(double)double2 { return double1*double2; } - (LargeIncrementerStruct)methodWithLargeStruct1:(LargeIncrementerStruct)struct1 andLargeStruct2:(LargeIncrementerStruct)struct2 { return (LargeIncrementerStruct){}; } - (void)methodWithNumber:(NSNumber *)number complexBlock:(ComplexIncrementerBlock)block { } - (NSString *)methodWithFooSuperclass:(FooSuperclass *)fooInstance { return @""; } - (void)methodWithPrimitivePointerArgument:(int *)arg { } - (void)methodWithObjectPointerArgument:(out id *)anObjectPointer { } @end ================================================ FILE: Spec/Support/SimpleKeyValueObserver.h ================================================ #import @interface SimpleKeyValueObserver : NSObject @property (nonatomic, copy, readonly) NSString *lastObservedKeyPath; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; @end ================================================ FILE: Spec/Support/SimpleKeyValueObserver.m ================================================ #import "SimpleKeyValueObserver.h" @interface SimpleKeyValueObserver () @property (nonatomic, copy, readwrite) NSString *lastObservedKeyPath; @end @implementation SimpleKeyValueObserver - (void)dealloc { self.lastObservedKeyPath = nil; [super dealloc]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { self.lastObservedKeyPath = keyPath; } @end ================================================ FILE: Spec/Support/SimpleMultiplier.h ================================================ #import @protocol SimpleMultiplier - (void)multiplyBy:(NSInteger)amount; - (void)multiplyByNumber:(NSNumber *)number; @end ================================================ FILE: Spec/Support/TestReporter.h ================================================ #import #import "Cedar.h" #import "CDRNullabilityCompat.h" NS_ASSUME_NONNULL_BEGIN @interface TestReporter : NSObject @property (nonatomic, readonly) NSArray *startedExamples; @property (nonatomic, readonly) NSArray *finishedExamples; @property (nonatomic, readonly) NSArray *startedExampleGroups; @property (nonatomic, readonly) NSArray *finishedExampleGroups; @end NS_ASSUME_NONNULL_END ================================================ FILE: Spec/Support/TestReporter.m ================================================ #import "TestReporter.h" #if !__has_feature(objc_arc) #error This class must be compiled with ARC. #endif @implementation TestReporter { NSMutableArray *_startedExamples; NSMutableArray *_finishedExamples; NSMutableArray *_startedExampleGroups; NSMutableArray *_finishedExampleGroups; } - (instancetype)init { if (self = [super init]) { _startedExamples = [NSMutableArray array]; _finishedExamples = [NSMutableArray array]; _startedExampleGroups = [NSMutableArray array]; _finishedExampleGroups = [NSMutableArray array]; } return self; } - (void)runWillStartWithGroups:(NSArray *)groups andRandomSeed:(unsigned int)seed {} - (void)runDidComplete {} - (int)result { return 0; } - (void)runWillStartExample:(CDRExample *)example { [_startedExamples addObject:example]; } - (void)runDidFinishExample:(CDRExample *)example { [_finishedExamples addObject:example]; } - (void)runWillStartExampleGroup:(CDRExampleGroup *)exampleGroup { [_startedExampleGroups addObject:exampleGroup]; } - (void)runDidFinishExampleGroup:(CDRExampleGroup *)exampleGroup { [_finishedExampleGroups addObject:exampleGroup]; } - (void)runWillStartSpec:(CDRSpec *)spec {} - (void)runDidFinishSpec:(CDRSpec *)spec {} @end ================================================ FILE: Spec/Swift/Spec-Bridging-Header.h ================================================ #import "ExpectFailureWithMessage.h" ================================================ FILE: Spec/Swift/SwiftSpec.swift ================================================ import Cedar #if !EXCLUDE_SWIFT_SPECS /// A very simple function for making assertions since Cedar provides no /// matchers usable from Swift private func expectThat(_ value: Bool, file: String = #file, line: UInt = #line) { if !value { (CDRSpecFailure.specFailure(withReason: "Expectation failed", fileName: file, lineNumber: Int32(line)) as AnyObject).raise() } } private var globalValue__: String? /// This mirrors `SpecSpec` class SwiftSpecSpec: CDRSpec { override func declareBehaviors() { describe("SwiftSpec") { beforeEach { // NSLog("=====================> I should run before all specs.") } afterEach { // NSLog("=====================> I should run after all specs.") } describe("a nested spec") { beforeEach { // NSLog("=====================> I should run only before the nested specs.") } afterEach { // NSLog("=====================> I should run only after the nested specs.") } it("should also run") { // NSLog("=====================> Nested spec") } it("should also also run") { // NSLog("=====================> Another nested spec") } } context("a nested spec (context)") { beforeEach { // NSLog("=====================> I should run only before the nested specs.") } afterEach { // NSLog("=====================> I should run only after the nested specs.") } it("should also run") { // NSLog("=====================> Nested spec") } it("should also also run") { // NSLog("=====================> Another nested spec") } } it("should run") { // NSLog("=====================> Spec") } it("should be pending", PENDING) it("should also be pending", nil) xit("should also be pending (xit)") {} describe("described specs should be pending", PENDING) describe("described specs should also be pending", nil) xdescribe("xdescribed specs should be pending") {} context("contexted specs should be pending", PENDING) context("contexted specs should also be pending", nil) xcontext("xcontexted specs should be pending") {}; describe("empty describe blocks should be pending") {} context("empty context blocks should be pending") {} } describe("subjectAction") { var value: Int = 0 subjectAction { value = 5 } beforeEach { value = 100 } it("should run after the beforeEach") { expectThat(value == 5) } describe("in a nested describe block") { beforeEach { value = 200 } it("should run after all the beforeEach blocks") { expectThat(value == 5) } } } describe("a describe block") { beforeEach { globalValue__ = nil } describe("that contains a beforeEach in a shared example group") { itShouldBehaveLike("a describe context that contains a beforeEach in a Swift shared example group") it("should not run the shared beforeEach before specs outside the shared example group") { expectThat(globalValue__ == nil) } } describe("that passes a value to the shared example context") { beforeEach { globalValue__ = "something" CDRSpecHelper.specHelper().sharedExampleContext["value"] = globalValue__ } itShouldBehaveLike("a Swift shared example group that receives a value in the context") } describe("that passes a value in-line to the shared example context") { beforeEach { globalValue__ = "something" } expectThat(globalValue__ == nil) itShouldBehaveLike("a Swift shared example group that receives a value in the context") { $0["value"] = globalValue__ } } itShouldBehaveLike("a Swift shared example group that contains a failing spec") } describe("a describe block that tries to include a shared example group that doesn't exist") { expectExceptionWithReason("Unknown shared example group with description: 'a unicorn'") { itShouldBehaveLike("a unicorn") } } } } class SharedExampleGroupPoolForSwiftSpecs: CDRSharedExampleGroupPool { override func declareSharedExampleGroups() { sharedExamplesFor("a describe context that contains a beforeEach in a Swift shared example group") { _ in beforeEach { expectThat(CDRSpecHelper.specHelper().sharedExampleContext.count == 0) globalValue__ = "" } it("should run the shared beforeEach before specs inside the shared example group") { expectThat(globalValue__ != nil) } } sharedExamplesFor("a Swift shared example group that receives a value in the context") { context in it("should receive the values set in the global shared example context") { expectThat((context["value"] as? String) == globalValue__) } } sharedExamplesFor("a Swift shared example group that contains a failing spec") { _ in it("should fail in the expected fashion") { expectFailureWithMessage("Expectation failed") { expectThat("wibble" == "wobble") } } } } } #endif ================================================ FILE: Spec/Swift/XCTAssertSpec.swift ================================================ import Cedar import XCTest class XCTAssertSpec: CDRSpec { override func declareBehaviors() { describe("XCTAssert calls in a Swift Cedar spec") { it("should allow a passing assertion") { XCTAssertEqual(1, 1) } it("should allow a failing assertion") { expectFailureWithMessage("XCTAssertEqual failed: (\"1\") is not equal to (\"2\") - Failure") { XCTAssertEqual(1, 2, "Failure") } } } } } ================================================ FILE: Spec/XCTest/CDRXCTestSuiteSpec.mm ================================================ #import "Cedar.h" #import "CDRXCTestSuite.h" #import "CDRReportDispatcher.h" #import "CDRXCTestSupport.h" #import "TestReporter.h" #if !__has_feature(objc_arc) #error This class must be compiled with ARC. #endif using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRXCTestSuiteSpec) xdescribe(@"CDRXCTestSuite", ^{ __block id subject; __block TestReporter *reporter; __block CDRReportDispatcher *dispatcher; beforeEach(^{ reporter = [TestReporter new]; dispatcher = [[CDRReportDispatcher alloc] initWithReporters:@[reporter]]; CDRDisableSpecValidation(); CDRSpec *simulatedSpec = [[NSClassFromString(@"CDRXCSimulatedTestSuiteSpec") alloc] init]; [simulatedSpec defineBehaviors]; CDREnableSpecValidation(); subject = [simulatedSpec testSuiteWithRandomSeed:0 dispatcher:dispatcher]; [subject performTest:nil]; }); it(@"should report that each parent example group has started and ended", ^{ reporter.startedExampleGroups.count should equal(4); reporter.finishedExampleGroups.count should equal(4); }); it(@"should report that pending examples have started and ended", ^{ NSPredicate *pendingPredicate = [NSPredicate predicateWithBlock:^BOOL(CDRExample *example, NSDictionary *_) { return example.state == CDRExampleStatePending; }]; [reporter.startedExamples filteredArrayUsingPredicate:pendingPredicate].count should equal(2); [reporter.finishedExamples filteredArrayUsingPredicate:pendingPredicate].count should equal(2); }); }); SPEC_END SPEC_BEGIN(CDRXCSimulatedTestSuiteSpec) describe(@"CDRXCSimulatedTestSuite", ^{ describe(@"with nested groups", ^{ describe(@"lots of nested groups", ^{ describe(@"no really, lots of nested groups", ^{ xit(@"should report pending examples before the first test to run", ^{ 1 should equal(2); }); it(@"should start and finish each example group", ^{ // nothing to see here }); xit(@"should report pending examples after the last test to run", ^{ 1 should equal(2); }); }); }); }); }); SPEC_END ================================================ FILE: Spec/iOS/CDRSpyiOSSpec.mm ================================================ #import #import "Cedar.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRSpyiOSSpec) describe(@"CDRSpy on iOS", ^{ context(@"when spying upon UITextField", ^{ __block UITextField *textField; beforeEach(^{ textField = [[[UITextField alloc] init] autorelease]; spy_on(textField); }); it(@"should handle isSecureTextEntry message which is proxied weirdly on iOS =< 6.1", ^{ [textField isSecureTextEntry]; }); }); }); SPEC_END ================================================ FILE: Spec/iOS/Cedar-iOSSpec.mm ================================================ // CDRSpecHelper.h should only be imported into this target from the iOS framework #import using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(iOSFrameworkSpecs) describe(@"Cedar-iOS", ^{ __block NSObject *object; beforeEach(^{ object = [[NSObject alloc] init]; }); it(@"should allow assertions", ^{ object should_not be_nil; object should_not be_same_instance_as([[NSObject alloc] init]); }); }); SPEC_END ================================================ FILE: Spec/iOS/CedarApplicationDelegateSpec.mm ================================================ #import "Cedar.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CedarApplicationDelegateSpec) describe(@"CedarApplicationDelegate", ^{ __block CedarApplicationDelegate *delegate; beforeEach(^{ delegate = [[[CedarApplicationDelegate alloc] init] autorelease]; }); describe(@"-window", ^{ it(@"should raise an educational exception", ^{ ^{ [delegate window]; } should raise_exception.with_reason(@"This Cedar iOS spec suite is run with the CedarApplicationDelegate. If your code needs the UIApplicationDelegate's window, you should stub this method to return an appropriate window."); }); }); }); SPEC_END ================================================ FILE: Spec/iOS/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: Spec/iOS/WeakReferenceCompatibilitySpec.mm ================================================ #import "Cedar.h" #import "ObjectWithWeakDelegate.h" #import "ARCViewController.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(WeakReferenceCompatibilitySpec) // This spec exists as a regression test to ensure that Cedar Doubles continue // to work with the iOS 5 runtime. // // For more info please see http://openradar.appspot.com/11117786 // or http://stackoverflow.com/questions/8675054/why-is-my-objects-weak-delegate-property-nil-in-my-unit-tests describe(@"An object with a weak reference to a Cedar Double", ^{ __block ObjectWithWeakDelegate *object; beforeEach(^{ id fakeDelegate = nice_fake_for(@protocol(ExampleDelegate)); object = [[[ObjectWithWeakDelegate alloc] init] autorelease]; object.delegate = fakeDelegate; }); it(@"should have the Double as a delegate", ^{ object.delegate should_not be_nil; }); describe(@"when sending a message", ^{ beforeEach(^{ [object tellTheDelegate]; }); it(@"should result in the double having received the message", ^{ object.delegate should have_received(@selector(someMessage)); }); }); }); describe(@"A UIViewController subclass compiled under ARC", ^{ NSString *systemVersion = [[UIDevice currentDevice] systemVersion]; NSInteger majorVersion = [[[systemVersion componentsSeparatedByString:@"."] objectAtIndex:0] integerValue]; if (majorVersion < 6) { describe(@"when tests are run on the iOS 5.x runtime", ^{ it(@"should be possible to spy directly on weak references, but isn't (http://openradar.appspot.com/11117786). Spy on a strong reference instead as a workaround.", PENDING); }); } else { __block ARCViewController *controller; beforeEach(^{ controller = [[[ARCViewController alloc] init] autorelease]; controller.view should_not be_nil; }); describe(@"spying on a weakly referred-to subview property", ^{ beforeEach(^{ spy_on(controller.weakSubview); [controller.weakSubview layoutIfNeeded]; }); it(@"should allow recording of sent messages, and not blow up on dealloc", ^{ controller.weakSubview should have_received("layoutIfNeeded"); }); }); describe(@"spying on a weakly referred-to child controller", ^{ beforeEach(^{ spy_on(controller.weakChildController); [controller.weakChildController isViewLoaded]; }); it(@"should allow recording of sent messages, and not blow up on dealloc", ^{ controller.weakChildController should have_received("isViewLoaded"); }); }); describe(@"spying on a weakly referred-to text field", ^{ beforeEach(^{ spy_on(controller.weakTextField); [controller.weakTextField becomeFirstResponder]; }); it(@"should allow recording of sent messages, and not blow up on dealloc", ^{ controller.weakTextField should have_received("becomeFirstResponder"); }); }); describe(@"spying on a weakly referred-to object not from UIKit", ^{ beforeEach(^{ spy_on(controller.weakObject); controller.weakObject stub_method("someMethod"); [controller.weakObject someMethod]; }); it(@"should allow recording of sent messages, and not blow up on dealloc", ^{ controller.weakObject should have_received("someMethod"); }); }); } }); SPEC_END ================================================ FILE: Spec/iOS/XCTest/CDRXTestSuiteSpec.mm ================================================ #import "Cedar.h" #import "CDRXCTestSuite.h" #import "CDRReportDispatcher.h" #import "CDRXCTestSupport.h" using namespace Cedar::Matchers; using namespace Cedar::Doubles; SPEC_BEGIN(CDRXCTestSuiteSpec) describe(@"CDRXCTestSuite", ^{ __block id subject; __block CDRReportDispatcher *dispatcher; static NSUInteger willStartExampleGroupCount; static NSUInteger didFinishExampleGroupCount; it(@"should report that each parent example group has started and ended to the dispatcher", ^{ willStartExampleGroupCount = 0; didFinishExampleGroupCount = 0; dispatcher = nice_fake_for([CDRReportDispatcher class]); dispatcher stub_method(@selector(runWillStartExampleGroup:)).and_do_block(^(CDRExampleGroup *group){ ++willStartExampleGroupCount; }); dispatcher stub_method(@selector(runDidFinishExampleGroup:)).and_do_block(^(CDRExampleGroup *group){ ++didFinishExampleGroupCount; }); CDRSpec *simulatedSpec = [[[NSClassFromString(@"CDRXSimulatedTestSuiteSpec") alloc] init] autorelease]; [simulatedSpec defineBehaviors]; subject = [simulatedSpec testSuiteWithRandomSeed:0 dispatcher:dispatcher]; [subject performTest:nil]; willStartExampleGroupCount should equal(4); didFinishExampleGroupCount should equal(4); }); }); SPEC_END SPEC_BEGIN(CDRXSimulatedTestSuiteSpec) describe(@"CDRXSimulatedTestSuite", ^{ describe(@"with nested groups", ^{ describe(@"lots of nested groups", ^{ describe(@"no really, lots of nested groups", ^{ it(@"should start and finish each example group", ^{ // nothing to see here }); }); }); }); }); SPEC_END ================================================ FILE: Spec/iOS/main.mm ================================================ #import #import int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([CedarApplicationDelegate class])); } } ================================================ FILE: Spec/main.mm ================================================ #import int main (int argc, const char *argv[]) { return CDRRunSpecs(); } ================================================ FILE: Spec/watchOS/App-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName Cedar watchOS Host App CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown WKCompanionAppBundleIdentifier io.pivotal.Cedar-watchOS-HostApp WKWatchKitApp ================================================ FILE: Spec/watchOS/Extension-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName Cedar-watchOS Specs Extension CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType XPC! CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 NSExtension NSExtensionAttributes WKAppBundleIdentifier io.pivotal.Cedar-watchOS-HostApp.watchkitapp NSExtensionPointIdentifier com.apple.watchkit RemoteInterfacePrincipalClass WKInterfaceController WKExtensionDelegateClassName ExtensionDelegate ================================================ FILE: Spec/watchOS/ExtensionDelegate.mm ================================================ #import #import @interface ExtensionDelegate : NSObject @end @implementation ExtensionDelegate - (void)applicationDidFinishLaunching { exit(CDRRunSpecs()); } @end ================================================ FILE: Spec/watchOS/Interface.storyboard ================================================ ================================================ FILE: install.sh ================================================ #!/bin/bash INSTALL_UUID=$(uuidgen) log() { printf "%b\n" "$*" } fail() { log "\nERROR: $*\n" log_event "Install Error" error "${*}" exit 1 } usage() { log "$0 [--head] [--version]" log "" log "Unless otherwise specified, the latest release of Cedar will be installed" log "" log "Options:" log " --head Gets the latest master revision of Cedar from github.com/cedarbdd/cedar." log " --version version_tag Gets the specified version from the version tag." } switch_to_tag() { # Defaults to latest version if not given VERSION_TAG="$1" [ "$VERSION_TAG" ] || VERSION_TAG=$(git for-each-ref refs/tags --sort=-refname --format="%(refname:short)" | grep v\\?\\d\\+\\.\\d\\+\\.\\d\\+ | ruby -e 'puts STDIN.read.split("\n").sort { |a,b| a.gsub("v", "").split(".").map(&:to_i) <=> b.gsub("v", "").split(".").map(&:to_i) }.last') git checkout "$VERSION_TAG" &>/dev/null || fail "Unable to find tag for version $VERSION_TAG" } log_event() { TOKEN=6bcfa72d98e6f7af1d647acfcd663051 EVENT=$1 PROPERTY_NAME=$2 PROPERTY_VALUE=$3 if [[ -n ${PROPERTY_NAME} ]] ; then PAYLOAD=$(echo '{"event": "'${EVENT}'", "properties": { "distinct_id":"'${INSTALL_UUID}'", "'${PROPERTY_NAME}'":"'${PROPERTY_VALUE}'", "token": "'${TOKEN}'" } }' | base64) else PAYLOAD=$(echo '{"event": "'${EVENT}'", "properties": { "distinct_id":"'${INSTALL_UUID}'", "token": "'${TOKEN}'" } }' | base64) fi curl 'https://api.mixpanel.com/track/?data='${PAYLOAD} > /dev/null 2>&1 } while (($# > 0)) do TOKEN="$1" case "$TOKEN" in --head|--HEAD|head|HEAD) GET_HEAD=1 shift ;; -version|--version) VERSION_TAG="v${2#v}" shift 2 ;; *) usage exit 1 ;; esac done if [[ -z "$(which git)" ]] ; then echo "Unable to find git. Have you installed Xcode as well as command line tools?" echo "You can install them from Xcode's Preferences, in the Downloads pane." fail "Could not find git; installation aborted." fi if [[ $GET_HEAD == 1 ]] ; then echo "Installing Cedar HEAD from master" elif [ "$VERSION_TAG" ] ; then echo "Installing Cedar version ${VERSION_TAG}" else echo "Installing latest Cedar release" fi rm -rf ~/.cedar > /dev/null echo "Cloning Cedar repo to ~/.cedar" git clone https://github.com/cedarbdd/cedar.git ~/.cedar > /dev/null 2>&1 if [[ $? != 0 ]] ; then fail "Unable to clone Cedar GitHub repo" fi cd ~/.cedar > /dev/null if [[ $GET_HEAD == 1 ]] ; then VERSION_TAG=$(git rev-parse HEAD) log_event "Install Script Run" version HEAD else switch_to_tag "$VERSION_TAG" log_event "Install Script Run" version "$VERSION_TAG" fi echo "Installing Cedar snippets and templates" ./installCodeSnippetsAndTemplates > /dev/null 2>&1 if [[ $? != 0 ]] ; then fail "Unable to install Cedar snippets and templates" fi echo "Cedar version $VERSION_TAG installed to ~/Library" log_event "Successful Install" ================================================ FILE: installCodeSnippetsAndTemplates ================================================ #!/bin/sh echo "\n===== Installing Code Snippets and Templates =====\n" if NOEXEC_DISABLE=1 rake clean uninstall install then echo "\n*** Restart Xcode/AppCode to load the new code snippets and templates. The templates are available under the Cedar section. ***\n" else echo "\n*** It seems something went wrong installing the code snippets and templates. Check the build output for errors. ***\n" exit 1 fi ================================================ FILE: scripts/rake/helpers/appcode.rb ================================================ require_relative 'shell' class AppCode def self.install_cedar_snippets(root_dir: ENV['HOME']) possible_appcode_directories(root_dir: root_dir).each do |full_snippets_dir| full_snippets_filepath = File.join(full_snippets_dir, APPCODE_SNIPPETS_FILENAME) Shell.run %{cp "#{APPCODE_SNIPPETS_FILE}" "#{full_snippets_filepath}"} end end def self.remove_installed_cedar_snippets possible_appcode_directories(root_dir: ENV['HOME']).each do |dir| Shell.run %{rm -f "#{File.join(dir, APPCODE_SNIPPETS_FILENAME)}"} end end private def self.possible_appcode_directories(root_dir: ENV['HOME']) appcode_pref_path = File.join(root_dir, 'Library', 'Preferences', 'appCode*') Dir.glob(appcode_pref_path, File::FNM_CASEFOLD).map { |d| File.join(d, "templates") } end # constants APPCODE_SNIPPETS_FILENAME = "Cedar.xml" APPCODE_SNIPPETS_FILE = File.join( ::PROJECT_ROOT, "CodeSnippetsAndTemplates", "AppCodeSnippets", APPCODE_SNIPPETS_FILENAME, ) end ================================================ FILE: scripts/rake/helpers/shell.rb ================================================ class Shell def self.run(cmd, logfile = nil) puts "#{green}==>#{clear} #{cmd}" original_cmd = cmd if logfile logfile = output_file(logfile) cmd = "export > #{logfile}; (#{cmd}) 2>&1 >> #{logfile}; test ${PIPESTATUS[0]} -eq 0" end system(cmd) or begin cmd_msg = "[#{red}Failed#{clear}] Command: #{original_cmd}" if logfile raise Exception.new < "CDRColorizedReporter"}) do begin kill # ensure simulator is not currently running Shell.run "rm -rf #{logfile}" Shell.run "ios-sim launch #{File.join(app_dir, "#{app_name}.app").inspect} --devicetypeid \"com.apple.CoreSimulator.SimDeviceType.iPhone-5s, #{SDK_RUNTIME_VERSION}\" --verbose --stdout #{logfile}" Shell.run "grep -q ', 0 failures' #{logfile}" # Fail unless we find the literal string '0 failures', this is to prevent the tests going green if the test runner itself crashes before it logs ANY output Shell.run "! grep -q ', [1-9][0-9]* failures' #{logfile}" # Fail if we find any number of failures rescue retry_count += 1 if retry_count == 3 raise else retry end end end end def self.launch_bundle(app_dir, app_name, test_bundle, logfile) env_vars = { "DYLD_INSERT_LIBRARIES" => "#{Xcode.developer_dir}/Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection", "XCInjectBundle" => test_bundle, "XCInjectBundleInto" => "#{File.join(Xcode.build_dir("-iphonesimulator"), "#{APP_IOS_NAME}.app/#{APP_IOS_NAME}")}", } Shell.with_env(env_vars) do launch(app_dir, app_name, logfile) end end def self.kill system %Q[killall -m -KILL "gdb" > /dev/null 2>&1] system %Q[killall -m -KILL "otest" > /dev/null 2>&1] system %Q[killall -m -KILL "iPhone Simulator" > /dev/null 2>&1] end end ================================================ FILE: scripts/rake/helpers/xcode.rb ================================================ require_relative 'shell' class Xcode def self.version `xcodebuild -version | grep Xcode`.chomp.split(' ').last.to_f end def self.developer_dir `xcode-select -print-path`.strip end def self.build_dir(effective_platform_name = "") File.join(BUILD_DIR, CONFIGURATION + effective_platform_name) end def self.sdk_dir_for_version(version) path = %x[ xcrun -sdk "iphonesimulator#{version}" -show-sdk-path 2>/dev/null ].strip raise("iPhone Simulator SDK version #{version} not installed") if $?.exitstatus != 0 path end def self.destination_for_ios_sdk(version) "name=iPhone 5s,OS=#{version}" end def self.swift_build_settings version >= 7.0 ? "" : "OTHER_SWIFT_FLAGS=-DEXCLUDE_SWIFT_SPECS" end def self.clean Shell.run "rm -rf '#{BUILD_DIR}'; true", "clean.build.log" Shell.run "rm -rf '#{DERIVED_DATA_DIR}'; true", "clean.derivedData.log" end def self.build(options = nil) raise "Options requires :target or :scheme" if !options[:target] and !options[:scheme] logfile = options.fetch(:logfile) args = options[:args] || "" args += " -target #{options[:target].inspect}" if options[:target] args += " -sdk #{options[:sdk].inspect}" if options[:sdk] args += " -scheme #{options[:scheme].inspect}" if options[:scheme] Shell.fold "build.#{options[:scheme] || options[:target]}" do Shell.run(%Q(xcodebuild -project #{PROJECT_NAME}.xcodeproj -configuration #{CONFIGURATION} SYMROOT=#{BUILD_DIR.inspect} clean build #{args}), logfile) end end def self.test(options = nil) raise "Options requires :target or :scheme" if !options[:target] and !options[:scheme] logfile = options.fetch(:logfile) args = options[:args] || "" args += " -target #{options[:target].inspect}" if options[:target] args += " -sdk #{options[:sdk].inspect}" if options[:sdk] args += " -scheme #{options[:scheme].inspect}" if options[:scheme] Shell.fold "test.#{options[:scheme] || options[:target]}" do Shell.run(%Q(xcodebuild -project #{PROJECT_NAME}.xcodeproj -configuration #{CONFIGURATION} -derivedDataPath #{DERIVED_DATA_DIR.inspect} SYMROOT=#{BUILD_DIR.inspect} clean build test #{args}), logfile) end end def self.analyze(options = nil) raise "Options requires :target or :scheme" if !options[:target] and !options[:scheme] logfile = options.fetch(:logfile) args = options[:args] || "" args += " -target #{options[:target].inspect}" if options[:target] args += " -sdk #{options[:sdk].inspect}" if options[:sdk] args += " -scheme #{options[:scheme].inspect}" if options[:scheme] Shell.fold "analyze.#{options[:scheme] || options[:target]}" do Shell.run(%Q[xcodebuild -project #{PROJECT_NAME}.xcodeproj -configuration #{CONFIGURATION} clean analyze #{args} SYMROOT='#{BUILD_DIR}'], logfile) end end def self.sed_project(search, replace) pbxproj = "#{PROJECT_NAME}.xcodeproj/project.pbxproj" contents = File.read(pbxproj) File.write(pbxproj, contents.gsub(search, replace)) end def self.template_directories [ "#{XCODE_TEMPLATES_DIR}/File Templates/Cedar", "#{XCODE_TEMPLATES_DIR}/Project Templates/Cedar" ] end end ================================================ FILE: scripts/rake/helpers.rb ================================================ require_relative 'helpers/appcode' require_relative 'helpers/shell' require_relative 'helpers/xcode' require_relative 'helpers/simulator' ================================================ FILE: scripts/rake/tasks/default.rb ================================================ # other, unrelated top level rake tasks desc 'Trims whitespace and runs all the tests (suites and bundles)' task :default => [:trim_whitespace, "suites:run", "suites:iosdynamicframeworkspecs:run", "testbundles:run"] desc 'Runs static analyzer on suites and the ios framework' task :analyze => [:clean, "suites:analyze", "suites:iosdynamicframeworkspecs:analyze"] desc 'Cleans, trims whitespace, runs all tests and static analyzer' task :full => [:clean, :default, :analyze] task :ci => [:clean, "testbundles:run", "suites:run", "suites:iosdynamicframeworkspecs:run"] desc "Trim whitespace" task :trim_whitespace do Shell.run %Q[git status --short | awk '{if ($1 != "D" && $1 != "R") print $2}' | grep -e '.*\.[cmh]$' | xargs sed -i '' -e 's/ / /g;s/ *$//g;'] end desc "Clean all targets" task :clean do Xcode.clean end ================================================ FILE: scripts/rake/tasks/dist.rb ================================================ # tasks for building a distribution of Cedar desc "Build a distribution of the templates and code snippets" task :dist => ["dist:prepare", "dist:package"] namespace :dist do task :prepare do Dir.mkdir(DIST_STAGING_DIR) unless File.exists?(DIST_STAGING_DIR) Shell.run %{rm -rf "#{DIST_STAGING_DIR}"/*} Shell.run %{mkdir -p "#{DIST_STAGING_DIR}/Library/Developer/Xcode"} Shell.run %{mkdir -p "#{DIST_STAGING_DIR}/Library/Developer/Xcode/UserData"} Shell.run %{cp "#{PROJECT_ROOT}/README.markdown" "#{DIST_STAGING_DIR}/README-Cedar.markdown"} Shell.run %{cp "#{PROJECT_ROOT}/MIT.LICENSE.txt" "#{DIST_STAGING_DIR}/LICENSE-Cedar.txt"} Shell.run %{cp -R "#{TEMPLATES_DIR}" "#{DIST_STAGING_DIR}/Library/Developer/Xcode/"} Shell.run %{cp -R "#{SNIPPETS_DIR}" "#{DIST_STAGING_DIR}/Library/Developer/Xcode/UserData/"} AppCode.install_cedar_snippets(root_dir: DIST_STAGING_DIR) end task :package do package_file_path = "#{BUILD_DIR}/Cedar-#{`git rev-parse --short HEAD`.strip}.tar.gz" Shell.run %{cd #{DIST_STAGING_DIR} ; tar --exclude .DS_Store -zcf "#{package_file_path}" * ; cd -} puts "" puts "*** Built tarball is in #{package_file_path} ***" puts "" end end ================================================ FILE: scripts/rake/tasks/frameworks.rb ================================================ # rake tasks related to building Cedar's frameworks namespace :frameworks do desc "Build Cedar OSX and iOS frameworks" task build: ['frameworks:ios:build', 'frameworks:osx:build'] namespace :osx do desc "Builds and installs the Cedar OS X framework" task :build do Xcode.build(target: CEDAR_FRAMEWORK_TARGET_NAME, logfile: "frameworks.osx.build.log", args: "install DSTROOT=/") end end namespace :ios do desc "Builds the legacy Cedar iOS static framework" task :build_static do Xcode.build(target: CEDAR_IOS_STATIC_FRAMEWORK_TARGET_NAME, logfile: "frameworks.ios.static.build.log") end desc "Builds the Cedar iOS dynamic framework" task :build do Xcode.build(target: CEDAR_IOS_DYNAMIC_FRAMEWORK_TARGET_NAME, logfile: "frameworks.ios.dynamic.build.log") end end end ================================================ FILE: scripts/rake/tasks/install.rb ================================================ # tasks related to install, uninstall, reinstall, etc... desc "Build frameworks and install templates and code snippets" task :install => [:clean, :uninstall, "dist:prepare"] do puts "" puts "Installing templates..." puts "" AppCode.install_cedar_snippets Shell.run %{rsync -vcrlK "#{DIST_STAGING_DIR}/Library/" ~/Library} end task :reinstall => [:uninstall] do Dir.mkdir(DIST_STAGING_DIR) unless File.exists?(DIST_STAGING_DIR) Shell.run %{rm -rf "#{DIST_STAGING_DIR}"/*} Shell.run %{mkdir -p "#{DIST_STAGING_DIR}/Library/Developer/Xcode"} Shell.run %{mkdir -p "#{DIST_STAGING_DIR}/Library/Developer/Xcode/UserData"} Shell.run %{cp "#{PROJECT_ROOT}/README.markdown" "#{DIST_STAGING_DIR}/README-Cedar.markdown"} Shell.run %{cp "#{PROJECT_ROOT}/MIT.LICENSE.txt" "#{DIST_STAGING_DIR}/LICENSE-Cedar.txt"} Shell.run %{cp -R "#{TEMPLATES_DIR}" "#{DIST_STAGING_DIR}/Library/Developer/Xcode/"} Shell.run %{cp -R "#{SNIPPETS_DIR}" "#{DIST_STAGING_DIR}/Library/Developer/Xcode/UserData/"} AppCode.install_cedar_snippets Shell.run %{rsync -vcrlK #{File.join(DIST_STAGING_DIR, "Library")} ~/Library} end desc "Build the frameworks and upgrade the target" task :upgrade, [:path_to_framework] do |task, args| usage_string = 'Usage: rake upgrade["/path/to/Cedar.framework"]' path_to_framework = args.path_to_framework raise "*** Missing path to the framework to be upgraded. ***\n#{usage_string}" unless path_to_framework path_to_framework = File.expand_path(path_to_framework) if File.directory?(path_to_framework) framework_folder = args.path_to_framework.split("/").last case framework_folder when "Cedar-iOS.framework" cedar_name = "Cedar-iOS" cedar_path = "#{CONFIGURATION}-iphoneuniversal" when "Cedar.framework" cedar_name = "Cedar" cedar_path = "#{CONFIGURATION}" end end raise "*** No framework found. ***\n#{usage_string}" unless cedar_path Rake::Task['frameworks:build'].invoke puts "" puts "Upgrading #{cedar_name} framework..." puts "" Shell.run %{rsync -vkcr --delete "#{BUILD_DIR}/#{cedar_path}/#{cedar_name}.framework/" "#{args.path_to_framework}/"} end desc "Remove code snippets and templates" task :uninstall do puts "" puts "Removing old templates..." puts "" Xcode.template_directories.each do |template_dir| next unless File.directory?(template_dir) Dir.foreach(template_dir) do |template| next if template == '.' || template == '..' template_plist = "#{template_dir}/#{template}/TemplateInfo.plist" next unless File.exists?(template_plist) if `#{PLISTBUDDY} -c "Print :Identifier" "#{template_plist}"`.start_with?(TEMPLATE_IDENTIFIER_PREFIX) || `#{PLISTBUDDY} -c "Print :#{TEMPLATE_SENTINEL_KEY}" "#{template_plist}"`.start_with?("true") Shell.run "rm -rf \"#{template_dir}/#{template}\"" end end end AppCode.remove_installed_cedar_snippets Shell.run "grep -Rl #{SNIPPET_SENTINEL_VALUE} #{XCODE_SNIPPETS_DIR} | xargs -I{} rm -f \"{}\"" end ================================================ FILE: scripts/rake/tasks/spec_suites.rb ================================================ # rake tasks related to running Cedar's spec suites desc 'Analyzes and runs specs, uispecs, and focused spec suites' task suites: ['suites:analyze', 'suites:run'] namespace :suites do desc 'Analyzes specs, uispecs, and focused spec suites' task analyze: ['specs:analyze', 'uispecs:analyze', 'focused_specs:analyze'] desc 'Runs specs, uispecs, and focused spec suites' task run: ['specs:run', 'uispecs:run', 'focused_specs:run'] desc "Analyzes and runs the Specs test suite" task specs: [:analyze, :run] namespace :specs do desc "Analyzes specs" task :analyze do Xcode.analyze(target: SPECS_TARGET_NAME, args: Xcode.swift_build_settings, logfile: "specs.analyze.log") end desc "Build specs" task build: 'frameworks:osx:build' do Xcode.build(target: SPECS_TARGET_NAME, args: Xcode.swift_build_settings, logfile: "specs.build.log") end desc "Run specs" task run: :build do build_dir = Xcode.build_dir("") Shell.with_env("DYLD_FRAMEWORK_PATH" => build_dir, "CEDAR_REPORTER_CLASS" => "CDRColorizedReporter") do Shell.run(File.join(build_dir, SPECS_TARGET_NAME).inspect, "Specs.log") end end end desc "Analyzes and runs the UISpecs test suite" task uispecs: ['uispecs:analyze', 'uispecs:run'] namespace :uispecs do desc "Analyzes UI specs" task :analyze do Xcode.analyze(target: UI_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386', logfile: "uispecs.analyze.log") end desc "Build UI specs" task :build do Xcode.build(target: UI_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386', logfile: "uispecs.build.log") end desc "Run UI specs" task run: :build do Simulator.kill env_vars = { "CEDAR_REPORTER_CLASS" => "CDRColorizedReporter", } Shell.with_env(env_vars) do Simulator.launch(Xcode.build_dir("-iphonesimulator"), UI_SPECS_TARGET_NAME, Xcode.build_dir("-uispecs.run.log")) end end end desc "Runs analyzer and focused test suite" task focused_specs: ['focused_specs:analyze', 'focused_specs:run'] namespace :focused_specs do # This target was made just for testing focused specs mode # and should not be created in applications that want to use Cedar. desc "Analyzes Cedar's focused specs tests suite" task :analyze do Xcode.analyze(target: FOCUSED_SPECS_TARGET_NAME, logfile: "focused_specs.analyze.log") end desc "Build Cedar's focused specs tests suite" task :build do Xcode.build(target: FOCUSED_SPECS_TARGET_NAME, logfile: "focused_specs.build.log") end desc "Run Cedar's specs for verifying focused test behavior" task run: :build do env_vars = { "DYLD_FRAMEWORK_PATH" => Xcode.build_dir, "CEDAR_REPORTER_CLASS" => "CDRColorizedReporter", } Shell.with_env(env_vars) do Shell.run(File.join(Xcode.build_dir, FOCUSED_SPECS_TARGET_NAME).inspect, "focused_specs.run.log") end end end desc "Analyzes and runs ios static framework specs" task iosstaticframeworkspecs: ['iosstaticframeworkspecs:analyze', 'iosstaticframeworkspecs:run'] namespace :iosstaticframeworkspecs do desc "Analyzes ios static framework specs" task :analyze do Xcode.analyze(target: IOS_STATIC_FRAMEWORK_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386', logfile: "frameworks.ios.static.specs.analyze.log") end desc "Build iOS static framework specs" task :build do Xcode.build(target: IOS_STATIC_FRAMEWORK_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386', logfile: "frameworks.ios.static.specs.build.log") end desc "Runs iOS static framework specs" task run: :build do Simulator.kill env_vars = { "CEDAR_REPORTER_CLASS" => "CDRColorizedReporter", } Shell.with_env(env_vars) do Simulator.launch(Xcode.build_dir("-iphonesimulator"), IOS_STATIC_FRAMEWORK_SPECS_TARGET_NAME, Xcode.build_dir("-frameworks.ios.static.specs.run.log")) end end end desc "Analyzes and runs ios dynamic framework specs" task iosdynamicframeworkspecs: ['iosdynamicframeworkspecs:analyze', 'iosdynamicframeworkspecs:run'] namespace :iosdynamicframeworkspecs do desc "Analyzes ios dynamic framework specs" task :analyze do Xcode.analyze(target: IOS_DYNAMIC_FRAMEWORK_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386 '+Xcode.swift_build_settings, logfile: "frameworks.ios.dynamic.specs.analyze.log") end desc "Build iOS dynamic framework specs" task :build do Xcode.build(target: IOS_DYNAMIC_FRAMEWORK_SPECS_TARGET_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: 'ARCHS=i386 '+Xcode.swift_build_settings, logfile: "frameworks.ios.dynamic.specs.build.log") end desc "Runs iOS dynamic framework specs" task run: :build do Simulator.kill env_vars = { "CEDAR_REPORTER_CLASS" => "CDRColorizedReporter", } Shell.with_env(env_vars) do Simulator.launch(Xcode.build_dir("-iphonesimulator"), IOS_DYNAMIC_FRAMEWORK_SPECS_TARGET_NAME, Xcode.build_dir("-frameworks.ios.dynamic.specs.run.log")) end end end end ================================================ FILE: scripts/rake/tasks/test_bundles.rb ================================================ # rake tasks for running Cedar's test bundle targets namespace :testbundles do desc "Runs all test bundle test suites" task run: ['testbundles:xctest'] desc "Converts the test bundle identifier to ones Xcode 5- recognizes (Xcode 6 postfixes the original bundler identifier)" task :convert_to_xcode5 do Xcode.sed_project(%r{com\.apple\.product-type\.bundle\.(oc)?unit-test}, 'com.apple.product-type.bundle') end desc "Build and run iOS XCTest spec bundle (#{IOS_SPEC_BUNDLE_SCHEME_NAME})" task xctest: :convert_to_xcode5 do Simulator.kill Xcode.test( scheme: IOS_SPEC_BUNDLE_SCHEME_NAME, sdk: "iphonesimulator#{SDK_VERSION}", args: "-destination '#{Xcode.destination_for_ios_sdk(SDK_RUNTIME_VERSION)}' -destination-timeout 9", logfile: "xctest.run.log", ) end end ================================================ FILE: scripts/rake/tasks/versioning.rb ================================================ # tasks related to setting / bumping Cedar's version number task :set_version, [:version_number] do |t, args| unless args[:version_number] raise Exception.new("Must specify version number. Aborting.") end version = args[:version_number] File.write("Source/Headers/Public/CDRVersion.h", "NSString *CDRVersion = @\"#{version}\";") podspec = File.read("Cedar.podspec") podspec.gsub!(/s\.version +=.+$/, "s.version = '#{version}'") podspec.gsub!(/:tag +=>.+$/, ":tag => 'v#{version}' }") File.write("Cedar.podspec", podspec) Shell.run "/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString #{version}\" Cedar-Info.plist" end task :tag_version, [:version_number] do |t, args| unless args[:version_number] raise Exception.new("Must specify version number. Aborting.") end unless system("git diff --quiet ") && system("git diff-index --quiet HEAD") raise Exception.new("Uncommitted changes. Aborting.") end Rake::Task['set_version'].invoke(args[:version_number]) Shell.run "git commit -am 'Update version to #{args[:version_number]}'" previously_latest_version = `git for-each-ref refs/tags --sort=-refname --format="%(refname:short)" | grep v\\\\?\\\\d\\\\+\\\\.\\\\d\\\\+\\\\.\\\\d\\\\+` .chomp .split("\n") .each { |version| version.gsub("v", "").split(".").map(&:to_i) } .sort { |a, b| a <=> b } .last template_file = Tempfile.new("tag-notes") template_file.write(system("git log --format=\"%h %s %b\" HEAD...#{previously_latest_version}")) template_file.close begin Shell.run "git tag v#{args[:version_number]} -F #{template_file.path.inspect}" ensure template_file.unlink end end ================================================ FILE: scripts/rake/tasks.rb ================================================ # specs require_relative 'tasks/spec_suites' require_relative 'tasks/test_bundles' # building frameworks require_relative 'tasks/frameworks' # distribution and (un|re)installation require_relative 'tasks/dist' require_relative 'tasks/install' require_relative 'tasks/versioning' # other top level rake tasks require_relative 'tasks/default' ================================================ FILE: scripts/set_git_sha_on_framework.rb ================================================ #!/usr/bin/ruby key = "CDRBuildVersionSHA" ver = `git rev-parse HEAD`.strip puts "Git commit SHA is #{ver}" path = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['INFOPLIST_PATH']}" puts "Updating #{path}" `/usr/libexec/PlistBuddy -c "Add :#{key} string #{ver}" "#{path}"` ================================================ FILE: upgradeCedarFramework ================================================ #!/bin/sh echo "\n===== Upgrading framework =====\n" TARGET_PATH=$1 if rake upgrade["$TARGET_PATH"] then echo "\n*** Finished upgrading the framework ***\n" else echo "\n*** It seems something went wrong with the upgrade. Make sure you supply the full path to the target framework i.e. path_to/Cedar-iOS.framework ***\n" fi