diff --git a/GHUnitIOS.framework/GHUnitIOS b/GHUnitIOS.framework/GHUnitIOS new file mode 120000 index 0000000..a82b1bb --- /dev/null +++ b/GHUnitIOS.framework/GHUnitIOS @@ -0,0 +1 @@ +Versions/Current/GHUnitIOS \ No newline at end of file diff --git a/GHUnitIOS.framework/Headers b/GHUnitIOS.framework/Headers new file mode 120000 index 0000000..a177d2a --- /dev/null +++ b/GHUnitIOS.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/GHUnitIOS.framework/Resources b/GHUnitIOS.framework/Resources new file mode 120000 index 0000000..953ee36 --- /dev/null +++ b/GHUnitIOS.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/GHUnitIOS.framework/Versions/A/GHUnitIOS b/GHUnitIOS.framework/Versions/A/GHUnitIOS new file mode 100644 index 0000000..b5829c5 Binary files /dev/null and b/GHUnitIOS.framework/Versions/A/GHUnitIOS differ diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHAsyncTestCase.h b/GHUnitIOS.framework/Versions/A/Headers/GHAsyncTestCase.h new file mode 100644 index 0000000..69335e4 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHAsyncTestCase.h @@ -0,0 +1,155 @@ +// +// GHAsyncTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 4/8/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import "GHTestCase.h" + +// Some default statuses to use; Or define and use your own +enum { + kGHUnitWaitStatusUnknown = 0, //!< Unknown wait status + kGHUnitWaitStatusSuccess, //!< Wait status success + kGHUnitWaitStatusFailure, //!< Wait status failure + kGHUnitWaitStatusCancelled //!< Wait status cancelled +}; + +/*! + Asynchronous test case with wait and notify. + + If notify occurs before wait has started (if it was a synchronous call), this test + case will still work. + + Be sure to call prepare before the asynchronous method (otherwise an exception will raise). + + @code + + @interface MyAsyncTest : GHAsyncTestCase { } + @end + + @implementation MyAsyncTest + + - (void)testSuccess { + [self prepare]; + + // Do asynchronous task here + [self performSelector:@selector(_succeed) withObject:nil afterDelay:0.1]; + + [self waitForStatus:kGHUnitWaitStatusSuccess timeout:1.0]; + } + + - (void)_succeed { + // Notice the forSelector points to the test above. This is so that + // stray notifies don't error or falsely succeed other tests. + // To ignore the check, forSelector can be NULL. + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testSuccess)]; + } + + @end + @endcode + */ +@interface GHAsyncTestCase : GHTestCase { + + NSInteger waitForStatus_; + NSInteger notifiedStatus_; + + BOOL prepared_; // Whether prepared was called before waitForStatus:timeout: + NSRecursiveLock *lock_; // Lock to synchronize on + SEL waitSelector_; // The selector we are waiting on + + NSArray *_runLoopModes; +} + +/*! + Run loop modes to run while waiting; + Defaults to NSDefaultRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode + */ +@property (retain, nonatomic) NSArray *runLoopModes; + +/*! + Prepare before calling the asynchronous method. + */ +- (void)prepare; + +/*! + Prepare and specify the selector we will use in notify. + @param selector + */ +- (void)prepare:(SEL)selector; + +/*! + Wait for notification of status or timeout. + + Be sure to prepare before calling your asynchronous method. + For example, + + @code + - (void)testFoo { + [self prepare]; + // Do asynchronous task here + [self waitForStatus:kGHUnitWaitStatusSuccess timeout:1.0]; + } + @endcode + + @param status kGHUnitWaitStatusSuccess, kGHUnitWaitStatusFailure or custom status + @param timeout Timeout in seconds + */ +- (void)waitForStatus:(NSInteger)status timeout:(NSTimeInterval)timeout; + +/*! + @deprecated + */ +- (void)waitFor:(NSInteger)status timeout:(NSTimeInterval)timeout; + +/*! + Wait for timeout to occur. + Fails if we did _NOT_ timeout. + @param timeout + */ +- (void)waitForTimeout:(NSTimeInterval)timeout; + +/*! + Notify waiting of status for test selector. + @param status Status, for example, kGHUnitWaitStatusSuccess + @param selector If not NULL, then will verify this selector is where we are waiting. + This prevents stray asynchronous callbacks to fail a later test + */ +- (void)notify:(NSInteger)status forSelector:(SEL)selector; + +/*! + Notify waiting of status for any selector. + @param status Status, for example, kGHUnitWaitStatusSuccess + */ +- (void)notify:(NSInteger)status; + +/*! + Run the run loops for the specified interval. + @param interval + @author Adapted from Robert Palmer, pauseForTimeout + */ +- (void)runForInterval:(NSTimeInterval)interval; + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTest+JUnitXML.h b/GHUnitIOS.framework/Versions/A/Headers/GHTest+JUnitXML.h new file mode 100644 index 0000000..17dc6f5 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTest+JUnitXML.h @@ -0,0 +1,44 @@ +// +// GHTest+JUnitXML.h +// GHUnit +// +// Created by Gabriel Handford on 6/4/10. +// Copyright 2010. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTest.h" + +@interface GHTest(JUnitXML) + +/*! + Return test results in JUnit XML format for external parsing use + (such as a Continuous Integration system like Hudson) + */ +- (NSString *)JUnitXML; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTest.h b/GHUnitIOS.framework/Versions/A/Headers/GHTest.h new file mode 100644 index 0000000..fd95ca2 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTest.h @@ -0,0 +1,187 @@ +// +// GHTest.h +// GHUnit +// +// Created by Gabriel Handford on 1/18/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import + + +/*! + Test status. + */ +typedef enum { + GHTestStatusNone = 0, + GHTestStatusRunning, // Test is running + GHTestStatusCancelling, // Test is being cancelled + GHTestStatusCancelled, // Test was cancelled + GHTestStatusSucceeded, // Test finished and succeeded + GHTestStatusErrored, // Test finished and errored +} GHTestStatus; + +enum { + GHTestOptionReraiseExceptions = 1 << 0, // Allows exceptions to be raised (so you can trigger the debugger) + GHTestOptionForceSetUpTearDownClass = 1 << 1, // Runs setUpClass/tearDownClass for this (each) test; Used when re-running a single test in a group +}; +typedef NSInteger GHTestOptions; + +/*! + Generate string from GHTestStatus + @param status + */ +extern NSString* NSStringFromGHTestStatus(GHTestStatus status); + +/*! + Check if test is running (or trying to cancel). + */ +extern BOOL GHTestStatusIsRunning(GHTestStatus status); + +/*! + Check if test has succeeded, errored or cancelled. + */ +extern BOOL GHTestStatusEnded(GHTestStatus status); + +/*! + Test stats. + */ +typedef struct { + NSInteger succeedCount; // Number of succeeded tests + NSInteger failureCount; // Number of failed tests + NSInteger cancelCount; // Number of aborted tests + NSInteger testCount; // Total number of tests +} GHTestStats; + +/*! + Create GHTestStats. + */ +extern GHTestStats GHTestStatsMake(NSInteger succeedCount, NSInteger failureCount, NSInteger cancelCount, NSInteger testCount); + +extern const GHTestStats GHTestStatsEmpty; + +extern NSString *NSStringFromGHTestStats(GHTestStats stats); + +@protocol GHTestDelegate; + +/*! + The base interface for a runnable test. + A runnable with a unique identifier, display name, stats, timer, delegate, log and error handling. + */ +@protocol GHTest + +- (void)run:(GHTestOptions)options; + +@property (readonly, nonatomic) NSString *identifier; // Unique identifier for test +@property (readonly, nonatomic) NSString *name; +@property (assign, nonatomic) NSTimeInterval interval; +@property (assign, nonatomic) GHTestStatus status; +@property (readonly, nonatomic) GHTestStats stats; +@property (retain, nonatomic) NSException *exception; +@property (assign, nonatomic, getter=isDisabled) BOOL disabled; +@property (assign, nonatomic, getter=isHidden) BOOL hidden; +@property (assign, nonatomic) id delegate; // weak + +- (NSArray *)log; + +- (void)reset; +- (void)cancel; + +- (NSInteger)disabledCount; + +@end + +/*! + Test delegate for notification when a test starts and ends. + */ +@protocol GHTestDelegate +- (void)testDidStart:(id)test source:(id)source; +- (void)testDidUpdate:(id)test source:(id)source; +- (void)testDidEnd:(id)test source:(id)source; +- (void)test:(id)test didLog:(NSString *)message source:(id)source; +@end + +/*! + Delegate which is notified of log messages from inside GHTestCase. + */ +@protocol GHTestCaseLogWriter +- (void)log:(NSString *)message testCase:(id)testCase; +@end + +/*! + Default test implementation with a target/selector pair. + - Tests a target and selector + - Notifies a test delegate + - Keeps track of status, running time and failures + - Stores any test specific logging + */ +@interface GHTest : NSObject { + + NSObject *delegate_; // weak + + id target_; + SEL selector_; + + NSString *identifier_; + NSString *name_; + GHTestStatus status_; + NSTimeInterval interval_; + BOOL disabled_; + BOOL hidden_; + NSException *exception_; // If failed + + NSMutableArray *log_; + +} + +@property (readonly, nonatomic) id target; +@property (readonly, nonatomic) SEL selector; +@property (readonly, nonatomic) NSArray *log; + +/*! + Create test with identifier, name. + @param identifier Unique identifier + @param name Name + */ +- (id)initWithIdentifier:(NSString *)identifier name:(NSString *)name; + +/*! + Create test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ +- (id)initWithTarget:(id)target selector:(SEL)selector; + +/*! + Create autoreleased test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ ++ (id)testWithTarget:(id)target selector:(SEL)selector; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestCase.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestCase.h new file mode 100644 index 0000000..635b252 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestCase.h @@ -0,0 +1,146 @@ +// +// GHTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 1/21/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// Copyright 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. +// + +#import "GHTestMacros.h" +#import "GHTest.h" + +/*! + Log to your test case logger. + For example, + @code + GHTestLog(@"Some debug info, %@", obj); + @endcode + */ +#define GHTestLog(...) [self log:[NSString stringWithFormat:__VA_ARGS__, nil]] + +/*! + The base class for a test case. + + @code + @interface MyTest : GHTestCase {} + @end + + @implementation MyTest + + // Run before each test method + - (void)setUp { } + + // Run after each test method + - (void)tearDown { } + + // Run before the tests are run for this class + - (void)setUpClass { } + + // Run before the tests are run for this class + - (void)tearDownClass { } + + // Tests are prefixed by 'test' and contain no arguments and no return value + - (void)testA { + GHTestLog(@"Log with a test with the GHTestLog(...) for test specific logging."); + } + + // Another test; Tests are run in lexical order + - (void)testB { } + + // Override any exceptions; By default exceptions are raised, causing a test failure + - (void)failWithException:(NSException *)exception { } + + @end + @endcode + + */ +@interface GHTestCase : NSObject { + id logWriter_; // weak + + SEL currentSelector_; +} + +//! The current test selector +@property (assign, nonatomic) SEL currentSelector; +@property (assign, nonatomic) id logWriter; + +// GTM_BEGIN +//! Run before each test method +- (void)setUp; + +//! Run after each test method +- (void)tearDown; + +/*! + By default exceptions are raised, causing a test failure + @brief Override any exceptions + @param exception Exception that was raised by test + */ +- (void)failWithException:(NSException*)exception; +// GTM_END + +//! Run before the tests (once per test case) +- (void)setUpClass; + +//! Run after the tests (once per test case) +- (void)tearDownClass; + +/*! + Whether to run the tests on a separate thread. Override this method in your + test case to override the default. + Default is NO, tests are run on a separate thread by default. + @result If YES runs on the main thread + */ +- (BOOL)shouldRunOnMainThread; + +//! Any special handling of exceptions after they are thrown; By default logs stack trace to standard out. +- (void)handleException:(NSException *)exception; + +/*! + Log a message, which notifies the log delegate. + This is not meant to be used directly, see GHTestLog(...) macro. + @param message + */ +- (void)log:(NSString *)message; + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup+JUnitXML.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup+JUnitXML.h new file mode 100644 index 0000000..ed4b4e7 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup+JUnitXML.h @@ -0,0 +1,42 @@ +// +// GHTestGroup+JUnitXML.h +// GHUnit +// +// Created by Gabriel Handford on 6/4/10. +// Copyright 2010. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTestGroup.h" + +@interface GHTestGroup(JUnitXML) + +- (NSString *)JUnitXML; + +- (BOOL)writeJUnitXMLAtPath:(NSString *)documentsPath error:(NSError **)error; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup.h new file mode 100644 index 0000000..1689410 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestGroup.h @@ -0,0 +1,176 @@ +// +// GHTestGroup.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTest.h" +#import "GHTestCase.h" + +/*! + @brief Interface for a group of tests. + + This group conforms to the GHTest protocol as well (see Composite pattern). + */ +@protocol GHTestGroup +- (NSString *)name; +- (id)parent; +- (NSArray *)children; +@end + +/*! + @brief A collection of tests (or test groups). + + A test group is a collection of id, that may represent a set of test case methods. + + For example, if you had the following GHTestCase. + + @code + @interface FooTest : GHTestCase {} + - (void)testFoo; + - (void)testBar; + @end + @endcode + + The GHTestGroup would consist of and array of GHTest, [FooTest#testFoo and FooTest#testBar], + each test being a target and selector pair. + + A test group may also consist of a group of groups (since GHTestGroup conforms to GHTest), + and this might represent a GHTestSuite. + */ +@interface GHTestGroup : NSObject { + + NSObject *delegate_; // weak + id parent_; // weak + + NSMutableArray */*of id*/children_; + + NSString *name_; // The name of the test group (usually the class name of the test case + NSTimeInterval interval_; // Total time of child tests + GHTestStatus status_; // Current status of the group (current status of running or completed child tests) + GHTestStats stats_; // Current stats for the group (aggregate of child test stats) + + BOOL didSetUpClass_; + + GHTestOptions options_; + + // Set if test is created from initWithTestCase:delegate: + // Allows use to perform setUpClass and tearDownClass (once per test case run) + id testCase_; + + NSException *exception_; // If exception happens in group setUpClass/tearDownClass +} + +@property (readonly, nonatomic) NSArray */*of id*/children; +@property (assign, nonatomic) id parent; +@property (readonly, nonatomic) id testCase; +@property (assign, nonatomic) GHTestOptions options; + +/*! + Create an empty test group. + @param name The name of the test group + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithName:(NSString *)name delegate:(id)delegate; + +/*! + Create test group from a test case. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithTestCase:(id)testCase delegate:(id)delegate; + +/*! + Create test group from a single test. + @param testCase + @param selector Test to run + @param delegate + */ +- (id)initWithTestCase:(id)testCase selector:(SEL)selector delegate:(id)delegate; + +/*! + Create test group from a test case. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ ++ (GHTestGroup *)testGroupFromTestCase:(id)testCase delegate:(id)delegate; + +/*! + Add a test case (or test group) to this test group. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + */ +- (void)addTestCase:(id)testCase; + +/*! + Add a test group to this test group. + @param testGroup Test group to add + */ +- (void)addTestGroup:(GHTestGroup *)testGroup; + +/*! + Add tests to this group. + @param tests Tests to add + */ +- (void)addTests:(NSArray */*of id*/)tests; + +/*! + Add test to this group. + @param test Test to add + */ +- (void)addTest:(id)test; + +/*! + Whether the test group should run on the main thread. + Call passes to test case instance if enabled. + */ +- (BOOL)shouldRunOnMainThread; + +/*! + @result YES if we have any enabled chilren, NO if all children have been disabled. + */ +- (BOOL)hasEnabledChildren; + +/*! + Get list of failed tests. + @result Failed tests + */ +- (NSArray */*of id*/)failedTests; + +/*! + Run in operation queue. + Tests from the group are added and will block until they have completed. + @param operationQueue If nil, then runs as is + @param options Options + */ +- (void)runInOperationQueue:(NSOperationQueue *)operationQueue options:(GHTestOptions)options; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestMacros.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestMacros.h new file mode 100644 index 0000000..ec0daea --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestMacros.h @@ -0,0 +1,1014 @@ +// +// GHTestMacros.h +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +// +// Portions of this file fall under the following license, marked with +// SENTE_BEGIN - SENTE_END +// +// Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved. +// +// Use of this source code is governed by the following license: +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Note: this license is equivalent to the FreeBSD license. +// +// This notice may not be removed from this file. + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// Copyright 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. +// + +/*! + @file GHTestMacros.h + @brief Assert macros for testing. + */ + +#import + +#import "NSException+GHTestFailureExceptions.h" +#import "NSValue+GHValueFormatter.h" + +// GTM_BEGIN + +extern NSString *const GHTestFilenameKey; +extern NSString *const GHTestLineNumberKey; +extern NSString *const GHTestFailureException; + +#if defined(__cplusplus) +extern "C" +#endif + +NSString *GHComposeString(NSString *, ...); + + +/*! + Generates a failure when a1 != noErr + @param a1 Should be either an OSErr or an OSStatus + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ...: A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNoErr(a1, description, ...) \ +do { \ +@try {\ +OSStatus a1value = (a1); \ +if (a1value != noErr) { \ +NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", a1value, #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 != a2 + @param a1 Rreceived value. Should be either an OSErr or an OSStatus + @param a2 Expected value. Should be either an OSErr or an OSStatus + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertErr(a1, a2, description, ...) \ +do { \ +@try {\ +OSStatus a1value = (a1); \ +OSStatus a2value = (a2); \ +if (a1value != a2value) { \ +NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, a2value, a1value, #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat:@"(%s) == (%s) fails", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +/*! + Generates a failure when a1 is NULL + @param a1 Should be a pointer (use GHAssertNotNil for an object) + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNotNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value == NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) != NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 is not NULL + @param a1 should be a pointer (use GHAssertNil for an object) + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value != NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) == NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 is equal to a2. This test is for C scalars, structs and unions. + @param a1 Argument 1 + @param a2 Argument 2 + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNotEquals(a1, a2, description, ...) \ +do { \ +@try {\ +if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2))) != 0) { \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:[@"Type mismatch -- " stringByAppendingString:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \ +NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \ +if ([a1encoded isEqualToValue:a2encoded]) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 is equal to a2. This test is for objects. + @param a1 Argument 1. object. + @param a2 Argument 2. object. + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNotEqualObjects(a1, a2, desc, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +id a2value = (a2); \ +if ( (strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \ +(strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \ +![(id)a1value isEqual:(id)a2value] ) continue; \ +NSString *_expression = [NSString stringWithFormat:@"%s('%@') != %s('%@')", #a1, [a1 description], #a2, [a2 description]]; \ +if (desc) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(desc, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(desc, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 is not 'op' to a2. This test is for C scalars. + @param a1 Argument 1 + @param a2 Argument 2 + @param op Operation + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertOperation(a1, a2, op, description, ...) \ +do { \ +@try {\ +if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2))) != 0) { \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:[@"Type mismatch -- " stringByAppendingString:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +if (!(a1value op a2value)) { \ +double a1DoubleValue = a1value; \ +double a2DoubleValue = a2value; \ +NSString *_expression = [NSString stringWithFormat:@"%s (%lg) %s %s (%lg)", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(description, ##__VA_ARGS__)]; \ +} \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:_expression]]; \ +} \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException \ +ghu_failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when a1 is not > a2. This test is for C scalars. + @param a1 argument 1 + @param a2 argument 2 + @param op operation + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertGreaterThan(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, >, description, ##__VA_ARGS__) + +/*! + Generates a failure when a1 is not >= a2. This test is for C scalars. + @param a1 argument 1 + @param a2 argument 2 + @param op operation + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertGreaterThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, >=, description, ##__VA_ARGS__) + +/*! + Generates a failure when a1 is not < a2. This test is for C scalars. + @param a1 argument 1 + @param a2 argument 2 + @param op operation + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertLessThan(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, <, description, ##__VA_ARGS__) + +/*! Generates a failure when a1 is not <= a2. This test is for C scalars. + @param a1 argument 1 + @param a2 argument 2 + @param op operation + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertLessThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, <=, description, ##__VA_ARGS__) + +/*! + Generates a failure when string a1 is not equal to string a2. This call + differs from GHAssertEqualObjects in that strings that are different in + composition (precomposed vs decomposed) will compare equal if their final + representation is equal. + ex O + umlaut decomposed is the same as O + umlaut composed. + @param a1 string 1 + @param a2 string 2 + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertEqualStrings(a1, a2, description, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +id a2value = (a2); \ +if (a1value == a2value) continue; \ +if ([a1value isKindOfClass:[NSString class]] && \ +[a2value isKindOfClass:[NSString class]] && \ +[a1value compare:a2value options:0] == NSOrderedSame) continue; \ +[self failWithException:[NSException ghu_failureInEqualityBetweenObject: a1value \ +andObject: a2value \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when string a1 is equal to string a2. This call + differs from GHAssertEqualObjects in that strings that are different in + composition (precomposed vs decomposed) will compare equal if their final + representation is equal. + ex O + umlaut decomposed is the same as O + umlaut composed. + @param a1 string 1 + @param a2 string 2 + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNotEqualStrings(a1, a2, description, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +id a2value = (a2); \ +if (([a1value isKindOfClass:[NSString class]] && \ +[a2value isKindOfClass:[NSString class]] && \ +[a1value compare:a2value options:0] != NSOrderedSame) || \ +(a1value == nil && [a2value isKindOfClass:[NSString class]]) || \ +(a2value == nil && [a1value isKindOfClass:[NSString class]]) \ +) continue; \ +[self failWithException:[NSException ghu_failureInInequalityBetweenObject: a1value \ +andObject: a2value \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when c-string a1 is not equal to c-string a2. + @param a1 string 1 + @param a2 string 2 + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertEqualCStrings(a1, a2, description, ...) \ +do { \ +@try {\ +const char* a1value = (a1); \ +const char* a2value = (a2); \ +if (a1value == a2value) continue; \ +if (strcmp(a1value, a2value) == 0) continue; \ +[self failWithException:[NSException ghu_failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \ +andObject: [NSString stringWithUTF8String:a2value] \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +/*! + Generates a failure when c-string a1 is equal to c-string a2. + @param a1 string 1 + @param a2 string 2 + @param description A format string as in the printf() function. Can be nil or an empty string but must be present. + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertNotEqualCStrings(a1, a2, description, ...) \ +do { \ +@try {\ +const char* a1value = (a1); \ +const char* a2value = (a2); \ +if (strcmp(a1value, a2value) != 0) continue; \ +[self failWithException:[NSException ghu_failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \ +andObject: [NSString stringWithUTF8String:a2value] \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// GTM_END + +// SENTE_BEGIN +/*! Generates a failure when !{ [a1 isEqualTo:a2] } is false + (or one is nil and the other is not). + @param a1 The object on the left + @param a2 The object on the right + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertEqualObjects(a1, a2, description, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +id a2value = (a2); \ +if (a1value == a2value) continue; \ +if ( (strcmp(@encode(__typeof__(a1value)), @encode(id)) == 0) && \ +(strcmp(@encode(__typeof__(a2value)), @encode(id)) == 0) && \ +[(id)a1value isEqual: (id)a2value] ) continue; \ +[self failWithException:[NSException ghu_failureInEqualityBetweenObject: a1value \ +andObject: a2value \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +/*! Generates a failure when a1 is not equal to a2. This test is for + C scalars, structs and unions. + @param a1 The argument on the left + @param a2 The argument on the right + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertEquals(a1, a2, description, ...) \ +do { \ +@try {\ +if ( strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2))) != 0 ) { \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:[@"Type mismatch -- " stringByAppendingString:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +NSValue *a1encoded = [NSValue value:&a1value withObjCType: @encode(__typeof__(a1))]; \ +NSValue *a2encoded = [NSValue value:&a2value withObjCType: @encode(__typeof__(a2))]; \ +if (![a1encoded isEqualToValue:a2encoded]) { \ +[self failWithException:[NSException ghu_failureInEqualityBetweenValue: a1encoded \ +andValue: a2encoded \ +withAccuracy: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +//! Absolute difference +#define GHAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right)) + + +/*! + Generates a failure when a1 is not equal to a2 within + or - accuracy is false. + This test is for scalars such as floats and doubles where small differences + could make these items not exactly equal, but also works for all scalars. + @param a1 The scalar on the left + @param a2 The scalar on the right + @param accuracy The maximum difference between a1 and a2 for these values to be considered equal + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \ +do { \ +@try {\ +if (strcmp(@encode(__typeof__(a1)), @encode(__typeof__(a2))) != 0) { \ +[self failWithException:[NSException ghu_failureInFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:[@"Type mismatch -- " stringByAppendingString:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +__typeof__(accuracy) accuracyvalue = (accuracy); \ +if (GHAbsoluteDifference(a1value, a2value) > accuracyvalue) { \ +NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \ +NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \ +NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \ +[self failWithException:[NSException ghu_failureInEqualityBetweenValue: a1encoded \ +andValue: a2encoded \ +withAccuracy: accuracyencoded \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + + +/*! Generates a failure unconditionally. + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHFail(description, ...) \ +[self failWithException:[NSException ghu_failureInFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]] + + + +/*! Generates a failure when a1 is not nil. + @param a1 An object + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertNil(a1, description, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +if (a1value != nil) { \ +NSString *_a1 = [NSString stringWithUTF8String: #a1]; \ +NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: NO \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) == nil fails", #a1] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +/*! Generates a failure when a1 is nil. + @param a1 An object + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertNotNil(a1, description, ...) \ +do { \ +@try {\ +id a1value = (a1); \ +if (a1value == nil) { \ +NSString *_a1 = [NSString stringWithUTF8String: #a1]; \ +NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: NO \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +}\ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) != nil fails", #a1] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +/*! + Generates a failure when expression evaluates to false. + @param expr The expression that is tested + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertTrue(expr, description, ...) \ +do { \ +BOOL _evaluatedExpression = (expr);\ +if (!_evaluatedExpression) {\ +NSString *_expression = [NSString stringWithUTF8String: #expr];\ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: YES \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} while (0) + + +/*! + Generates a failure when expression evaluates to false and in addition will + generate error messages if an exception is encountered. + + @param expr The expression that is tested + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertTrueNoThrow(expr, description, ...) \ +do { \ +@try {\ +BOOL _evaluatedExpression = (expr);\ +if (!_evaluatedExpression) {\ +NSString *_expression = [NSString stringWithUTF8String: #expr];\ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: NO \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while (0) + + +/*! Generates a failure when the expression evaluates to true. + @param expr The expression that is tested + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertFalse(expr, description, ...) \ +do { \ +BOOL _evaluatedExpression = (expr);\ +if (_evaluatedExpression) {\ +NSString *_expression = [NSString stringWithUTF8String: #expr];\ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: NO \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} while (0) + + +/*! Generates a failure when the expression evaluates to true and in addition + will generate error messages if an exception is encountered. + @param expr The expression that is tested + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertFalseNoThrow(expr, description, ...) \ +do { \ +@try {\ +BOOL _evaluatedExpression = (expr);\ +if (_evaluatedExpression) {\ +NSString *_expression = [NSString stringWithUTF8String: #expr];\ +[self failWithException:[NSException ghu_failureInCondition: _expression \ +isTrue: YES \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException ghu_failureInRaise:[NSString stringWithFormat: @"!(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while (0) + + +/*! Generates a failure when expression does not throw an exception. + @param expression The expression that is evaluated + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent. + */ +#define GHAssertThrows(expr, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (id anException) { \ +continue; \ +}\ +[self failWithException:[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +} while (0) + + +/*! Generates a failure when expression does not throw an exception of a + specific class. + @param expression The expression that is evaluated + @param specificException The specified class of the exception + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertThrowsSpecific(expr, specificException, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +} while (0) + + +/*! Generates a failure when expression does not throw an exception of a + specific class with a specific name. Useful for those frameworks like + AppKit or Foundation that throw generic NSException w/specific names + (NSInvalidArgumentException, etc). + @param expression The expression that is evaluated + @param specificException The specified class of the exception + @param aName The name of the specified exception + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) continue; \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +} while (0) + + +/*! Generates a failure when expression does throw an exception. + @param expression The expression that is evaluated + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertNoThrow(expr, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (id anException) { \ +[self failWithException:[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while (0) + + +/*! Generates a failure when expression does throw an exception of the specitied + class. Any other exception is okay (i.e. does not generate a failure). + @param expression The expression that is evaluated + @param specificException The specified class of the exception + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertNoThrowSpecific(expr, specificException, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +[self failWithException:[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +@catch (id anythingElse) {\ +; \ +}\ +} while (0) + + +/*! Generates a failure when expression does throw an exception of a + specific class with a specific name. Useful for those frameworks like + AppKit or Foundation that throw generic NSException w/specific names + (NSInvalidArgumentException, etc). + @param expression The expression that is evaluated. + @param specificException The specified class of the exception + @param aName The name of the specified exception + @param description A format string as in the printf() function. Can be nil or an empty string but must be present + @param ... A variable number of arguments to the format string. Can be absent + */ +#define GHAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) { \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException ghu_failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +} \ +continue; \ +}\ +@catch (id anythingElse) {\ +; \ +}\ +} while (0) + + +//! @cond DEV + +@interface NSException(GHTestMacros_GTMSenTestAdditions) ++ (NSException *)ghu_failureInFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInCondition:(NSString *)condition + isTrue:(BOOL)isTrue + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInEqualityBetweenObject:(id)left + andObject:(id)right + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInInequalityBetweenObject:(id)left + andObject:(id)right + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInEqualityBetweenValue:(NSValue *)left + andValue:(NSValue *)right + withAccuracy:(NSValue *)accuracy + inFile:(NSString *)filename + atLine:(int) ineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInRaise:(NSString *)expression + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInRaise:(NSString *)expression + exception:(NSException *)exception + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; +@end + +//! @endcond + +// SENTE_END diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestOperation.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestOperation.h new file mode 100644 index 0000000..880711f --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestOperation.h @@ -0,0 +1,46 @@ +// +// GHTestOperation.h +// GHUnit +// +// Created by Gabriel Handford on 6/4/10. +// Copyright 2010. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTest.h" + +/*! + Test for running in the context of an NSOperationQueue. + */ +@interface GHTestOperation : NSOperation { + id test_; + GHTestOptions options_; +} + +- (id)initWithTest:(id)test options:(GHTestOptions)options; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestRunner.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestRunner.h new file mode 100644 index 0000000..b038e4e --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestRunner.h @@ -0,0 +1,162 @@ +// +// GHTestRunner.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2008 Gabriel Handford +// +// 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. +// + +//! @cond DEV + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// Copyright 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. +// + +#import "GHTestGroup.h" +#import "GHTestSuite.h" + +@class GHTestRunner; + +// Delegates can be guaranteed to be notified on the main thread (using #delegateOnMainThread) +@protocol GHTestRunnerDelegate +@optional +- (void)testRunnerDidStart:(GHTestRunner *)runner; +- (void)testRunner:(GHTestRunner *)runner didStartTest:(id)test; // Test started +- (void)testRunner:(GHTestRunner *)runner didUpdateTest:(id)test; // Test changed +- (void)testRunner:(GHTestRunner *)runner didEndTest:(id)test; // Test finished +- (void)testRunnerDidCancel:(GHTestRunner *)runner; +- (void)testRunnerDidEnd:(GHTestRunner *)runner; + +- (void)testRunner:(GHTestRunner *)runner didLog:(NSString *)message; // Runner logged message +- (void)testRunner:(GHTestRunner *)runner test:(id)test didLog:(NSString *)message; // Test logged message +@end + +/*! + Runs the tests. + Tests are run a separate thread though delegates are called on the + main thread by default (see #delegateOnMainThread). + */ +@interface GHTestRunner : NSObject { + + id test_; // The test to run; Could be a GHTestGroup (suite), GHTestGroup (test case), or GHTest (target/selector) + + NSObject *delegate_; // weak + + GHTestOptions options_; + + BOOL running_; + BOOL cancelling_; + + NSTimeInterval startInterval_; + + NSOperationQueue *operationQueue_; //! If running a suite in operation queue +} + +@property (retain) id test; +@property (assign) NSObject *delegate; +@property (assign) GHTestOptions options; +@property (readonly) GHTestStats stats; +@property (readonly, getter=isRunning) BOOL running; +@property (readonly, getter=isCancelling) BOOL cancelling; +@property (readonly) NSTimeInterval interval; +@property (retain, nonatomic) NSOperationQueue *operationQueue; + + +/*! + Create runner for test. + @param test + */ +- (id)initWithTest:(id)test; + +/*! + Create runner for all tests. + @see GHTesting#loadAllTestCases. + @result Runner + */ ++ (GHTestRunner *)runnerForAllTests; + +/*! + Create runner for test suite. + @param suite + @result Runner + */ ++ (GHTestRunner *)runnerForSuite:(GHTestSuite *)suite; + +/*! + Create runner for class and method. + @param testClassName + @param methodName + @result Runner + */ ++ (GHTestRunner *)runnerForTestClassName:(NSString *)testClassName methodName:(NSString *)methodName; + +/*! + Get the runner from the environment. + If the TEST env is set, then we will only run that test case or test method. + */ ++ (GHTestRunner *)runnerFromEnv; + +/*! + Run the test runner. Usually called from the test main. + Reads the TEST environment variable and filters on that; or all tests are run. + @result 0 is success, otherwise the failure count + */ ++ (int)run; + +- (void)runInBackground; + +/*! + Start the test runner with the default test. + @result 0 is success, otherwise the failure count + */ +- (int)runTests; + +- (void)cancel; + +- (void)setInParallel:(BOOL)inParallel; +- (BOOL)isInParallel; + +/*! + Write message to console. + */ +- (void)log:(NSString *)message; + +@end + +//! @endcond + diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestSuite.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestSuite.h new file mode 100644 index 0000000..6d4295b --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestSuite.h @@ -0,0 +1,118 @@ +// +// GHTestSuite.h +// GHUnit +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTestGroup.h" + +/*! + If set, will run it as a "test filter" like the env variable TEST. + */ +extern NSString *GHUnitTest; + + +/*! + Test suite is an alias for test group. + + A test case is an instance of a test case class with test methods. + A test is a id which represents a target and a selector. + A test group is a collection of tests; A collection of id (GHTest or GHTestGroup). + + For example, if you have 2 test cases, GHTestCase1 (with some test methods) and GHTestCase2 (with some test methods), + your test suite might look like: + +"Tests" (GHTestSuite) + GHTestGroup (collection of tests from GHTestCase1) + - (void)testA1 (GHTest with target GHTestCase1 + testA1) + - (void)testA2 (GHTest with target GHTestCase1 + testA2) + GHTestGroup (collection of tests from GHTestCase2) + - (void)testB1; (GHTest with target GHTestCase2 + testB1) + - (void)testB2; (GHTest with target GHTestCase2 + testB2) + + */ +@interface GHTestSuite : GHTestGroup { } + +/*! + Create test suite with test cases. + @param name Label to give the suite + @param testCases Array of init'ed test case classes + @param delegate + */ +- (id)initWithName:(NSString *)name testCases:(NSArray *)testCases delegate:(id)delegate; + +/*! + Creates a suite of all tests. + Will load all classes that subclass from GHTestCase, SenTestCase or GTMTestCase (or register test case class). + @result Suite + */ ++ (GHTestSuite *)allTests; + +/*! + Create suite of tests with filter. + This is useful for running a single test or all tests in a single test case. + + For example, + 'GHSlowTest' -- Runs all test method in GHSlowTest + 'GHSlowTest/testSlowA -- Only runs the test method testSlowA in GHSlowTest + + @param testFilter Test filter + @result Suite + */ ++ (GHTestSuite *)suiteWithTestFilter:(NSString *)testFilter; + +/*! + Create suite of tests that start with prefix. + @param prefix If test case class starts with the prefix; If nil or empty string, returns all tests + @param options Compare options + */ ++ (GHTestSuite *)suiteWithPrefix:(NSString *)prefix options:(NSStringCompareOptions)options; + +/*! + Suite for a single test/method. + @param testCaseClass + @param method + @result Suite + */ ++ (GHTestSuite *)suiteWithTestCaseClass:(Class)testCaseClass method:(SEL)method; + +/*! + Return test suite based on environment (TEST=TestFoo/foo) + @result Suite + */ ++ (GHTestSuite *)suiteFromEnv; + +@end + +@interface GHTestSuite (JUnitXML) + +- (BOOL)writeJUnitXML:(NSError **)error; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTestViewModel.h b/GHUnitIOS.framework/Versions/A/Headers/GHTestViewModel.h new file mode 100644 index 0000000..4abf05e --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTestViewModel.h @@ -0,0 +1,169 @@ +// +// GHTest.h +// GHUnit +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +#import "GHTestGroup.h" +#import "GHTestSuite.h" +#import "GHTestRunner.h" + +@class GHTestNode; + +@protocol GHTestNodeDelegate +- (void)testNodeDidChange:(GHTestNode *)node; +@end + +typedef enum { + GHTestNodeFilterNone = 0, + GHTestNodeFilterFailed = 1 +} GHTestNodeFilter; + +/*! + Test view model for use in a tree view. + */ +@interface GHTestViewModel : NSObject { + + NSString *identifier_; + GHTestSuite *suite_; + GHTestNode *root_; + + GHTestRunner *runner_; + + NSMutableDictionary *map_; // id#identifier -> GHTestNode + + BOOL editing_; + + NSMutableDictionary *defaults_; +} + +@property (readonly, nonatomic) GHTestNode *root; +@property (assign, nonatomic, getter=isEditing) BOOL editing; + +/*! + Create view model with root test group node. + @param identifier Unique identifier for test model (used to load defaults) + @param suite + */ +- (id)initWithIdentifier:(NSString *)identifier suite:(GHTestSuite *)suite; + +- (NSString *)name; +- (NSString *)statusString:(NSString *)prefix; + +/*! + Get the test node from the test. + @param test + */ +- (GHTestNode *)findTestNode:(id)test; + +- (GHTestNode *)findFailure; +- (GHTestNode *)findFailureFromNode:(GHTestNode *)node; + +/*! + Register node, so that we can do a lookup later (see #findTestNode). + @param node + */ +- (void)registerNode:(GHTestNode *)node; + +// Return number of test groups +- (NSInteger)numberOfGroups; + +// Return number of tests in group +- (NSInteger)numberOfTestsInGroup:(NSInteger)group; + +/*! + Search for path to test. + @param test + @result Index path + */ +- (NSIndexPath *)indexPathToTest:(id)test; + +- (void)loadDefaults; +- (void)saveDefaults; + +/*! + Run with current test suite. + */ +- (void)run:(id)delegate inParallel:(BOOL)inParallel options:(GHTestOptions)options; + +- (void)cancel; + +- (BOOL)isRunning; + +@end + + +@interface GHTestNode : NSObject { + + id test_; + NSMutableArray */*of GHTestNode*/children_; + NSMutableArray */* of GHTestNode*/filteredChildren_; + + id delegate_; + GHTestNodeFilter filter_; + NSString *textFilter_; +} + +@property (readonly, nonatomic) NSArray */* of GHTestNode*/children; +@property (readonly, nonatomic) id test; +@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) GHTestNodeFilter filter; +@property (retain, nonatomic) NSString *textFilter; + +- (id)initWithTest:(id)test children:(NSArray */*of id*/)children source:(GHTestViewModel *)source; ++ (GHTestNode *)nodeWithTest:(id)test children:(NSArray */*of id*/)children source:(GHTestViewModel *)source; + +- (NSString *)identifier; +- (NSString *)name; +- (NSString *)nameWithStatus; + +- (GHTestStatus)status; +- (NSString *)statusString; +- (NSString *)stackTrace; +- (NSString *)exceptionFilename; +- (NSInteger)exceptionLineNumber; +- (NSString *)log; +- (BOOL)isRunning; +- (BOOL)isDisabled; +- (BOOL)isHidden; +- (BOOL)isEnded; +- (BOOL)isGroupTest; // YES if test has "sub tests" + +- (BOOL)isSelected; +- (void)setSelected:(BOOL)selected; + +- (BOOL)hasChildren; +- (BOOL)failed; + +- (void)notifyChanged; + +- (void)setFilter:(GHTestNodeFilter)filter textFilter:(NSString *)textFilter; + +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHTesting.h b/GHUnitIOS.framework/Versions/A/Headers/GHTesting.h new file mode 100644 index 0000000..947dae4 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHTesting.h @@ -0,0 +1,151 @@ +// +// GHTesting.h +// GHUnit +// +// Created by Gabriel Handford on 1/30/09. +// Copyright 2008 Gabriel Handford +// +// 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. +// + +//! @cond DEV + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// Copyright 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. +// + +#import +#import "GHUnit.h" + +#ifdef __cplusplus +extern "C" NSString *GHUStackTraceFromException(NSException *e); +#else +extern NSString *GHUStackTraceFromException(NSException *e); +#endif + +// GTM_BEGIN +BOOL isTestFixtureOfClass(Class aClass, Class testCaseClass); +// GTM_END + +/*! + Utility test for loading and running tests. + @note Much of this is borrowed from GTM/UnitTesting. + */ +@interface GHTesting : NSObject { + + NSMutableArray/* of NSString*/ *testCaseClassNames_; + +} + +/*! + The shared testing instance. + */ ++ (GHTesting *)sharedInstance; + +/*! + Load all test classes that we can "see". + @result Array of initialized (and autoreleased) test case classes in an autoreleased array. + */ +- (NSArray *)loadAllTestCases; + +/*! + Load tests from target. + @result Array of id + */ +- (NSArray *)loadTestsFromTarget:(id)target; + +/*! + See if class is of a registered test case class. + */ +- (BOOL)isTestCaseClass:(Class)aClass; + +/*! + Register test case class. + @param aClass + */ +- (void)registerClass:(Class)aClass; + +/*! + Register test case class by name. + @param className Class name (via NSStringFromClass(aClass) + */ +- (void)registerClassName:(NSString *)className; + +/*! + Format test exception. + @param exception + @result Description + */ ++ (NSString *)descriptionForException:(NSException *)exception; + +/*! + Filename for cause of test exception. + @param test + @result Filename + */ ++ (NSString *)exceptionFilenameForTest:(id)test; + +/*! + Line number for cause of test exception. + @param test + @result Line number + */ ++ (NSInteger)exceptionLineNumberForTest:(id)test; + +/*! + Run test. + @param target + @param selector + @param exception Exception, if set, is retained and should be released by the caller. + @param interval Time to run the test + @param reraiseExceptions If YES, will re-raise exceptions + */ ++ (BOOL)runTestWithTarget:(id)target selector:(SEL)selector exception:(NSException **)exception + interval:(NSTimeInterval *)interval reraiseExceptions:(BOOL)reraiseExceptions; + +/*! + Same as normal runTest without catching exceptions. + */ ++ (BOOL)runTestOrRaiseWithTarget:(id)target selector:(SEL)selector exception:(NSException **)exception interval:(NSTimeInterval *)interval; + +@end + +@protocol GHSenTestCase +- (void)raiseAfterFailure; +@end + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnit.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnit.h new file mode 100644 index 0000000..d7f940c --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnit.h @@ -0,0 +1,723 @@ +// +// GHUnit.h +// GHUnit +// +// Created by Gabriel Handford on 1/19/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import "GHTestCase.h" +#import "GHAsyncTestCase.h" +#import "GHTestSuite.h" +#import "GHTestMacros.h" +#import "GHTestRunner.h" + +#import "GHTest.h" +#import "GHTesting.h" +#import "GHTestOperation.h" +#import "GHTestGroup.h" +#import "GHTest+JUnitXML.h" +#import "GHTestGroup+JUnitXML.h" +#import "NSException+GHTestFailureExceptions.h" +#import "NSValue+GHValueFormatter.h" + +#if TARGET_OS_IPHONE +#import "GHUnitIOSAppDelegate.h" +#endif + +#ifdef DEBUG +#define GHUDebug(fmt, ...) do { \ +fputs([[[NSString stringWithFormat:fmt, ##__VA_ARGS__] stringByAppendingString:@"\n"] UTF8String], stdout); \ +} while(0) +#else +#define GHUDebug(fmt, ...) do {} while(0) +#endif + +/*! + @mainpage GHUnit + + + GHUnit is a test framework for Objective-C (Mac OS X 10.5 and above and iPhone 3.x and above). + It can be used with SenTestingKit, GTM or all by itself. + + For example, your test cases will be run if they subclass any of the following: + + - GHTestCase + - SenTestCase + - GTMTestCase + + + Source: http://github.com/gabriel/gh-unit + + View docs online: http://gabriel.github.com/gh-unit/ + + + This manual is divided in the following sections: + - @subpage Installing + - @subpage Examples + - @subpage CommandLine "Command Line & Makefiles" + - @subpage TestMacros + - @subpage Building + - @subpage EnvVariables + - @subpage Customizing + - @subpage Hudson + + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/GHUnit-IPhone-0.4.18.png + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/GHUnit-0.4.18.png + + @section Notes Notes + + GHUnit was inspired by and uses parts of GTM (google-toolbox-for-mac) code, mostly from UnitTesting: http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/UnitTesting/ + + */ + +/*! + @page Installing Installing + + @ref InstallingIOSXcode4 + + @ref InstallMacOSXXcode4 + + @subpage InstallingXcode3 + + @section InstallingIOSXcode4 Installing in Xcode 4 (iOS) + + @subsection CreateTestTargetXcode4 Create a Test Target + + - You'll want to create a separate Test target. Select the project file for your app in the Project Navigator. From there, select the Add Target + symbol at the bottom of the window. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/1_add_target.png + + - Select iOS, Application, Window-based Application. Select Next. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/2_select_application.png + + - Name it Tests or something similar. Select Finish. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/3_name_it.png + + @subsection ConfigureTestTargetXcode4 Configure the Test Target + + - Download and copy the GHUnitIOS.framework to your project. Command click on Frameworks in the Project Navigator and select: Add Files to "MyTestable"... + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/6_add_framework.png + + - Select GHUnitIOS.framework and make sure the only the Tests target is selected. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/7_add_framework_dialog.png + + - We want to enable use of Objective-C categories, which isn't enabled for static libraries by default. In the Tests target, Build Settings, under Other Linker Flags, add -ObjC and -all_load. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/8_other_linker_flags.png + + - Select and delete the files from the existing Tests folder. Leave the Supporting Files folder. GHUnit will provide the application delegate below. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/9_remove_test_files.png + + - By default, the Tests-Info.plist file includes MainWindow_iPhone and MainWindow_iPad for Main nib file base name. You should remove both these fields. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/9b_fix_plist.png + + - After removing these entries, the Tests-Info.plist should look like this. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/9c_fixed_plist.png + + - In Tests folder, in Supporting Files, main.m, replace the last argument of UIApplicationMain with @"GHUnitIPhoneAppDelegate". + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/10_main.png + + - Select the Tests target, iPhone Simulator configuration: + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/11_select_target.png + + - Hit Run, and you'll hopefully see the test application running (but without any tests). + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/12_running.png + + @subsection CreateTestXcode4 Create a Test + + - Command click on the Tests folder and select: New File... + - Under iOS, Cocoa Touch, select Objective-C class and select Next. Leave the default subclass and select Next again. + - Name the file MyTest.m and make sure its enabled only for the "Tests" target. + - Delete the MyTest.h file and replace the MyTest.m file with: + + @code + #import + + @interface MyTest : GHTestCase { } + @end + + @implementation MyTest + + - (void)testStrings { + NSString *string1 = @"a string"; + GHTestLog(@"I can log to the GHUnit test console: %@", string1); + + // Assert string1 is not NULL, with no custom error description + GHAssertNotNULL(string1, nil); + + // Assert equal objects, add custom error description + NSString *string2 = @"a string"; + GHAssertEqualObjects(string1, string2, @"A custom error message. string1 should be equal to: %@.", string2); + } + + @end + @endcode + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/13_adding_test.png + + - Now run the "Tests" target. Hit the Run button in the top right. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/Installing/14_running_with_test.png + + @subsection InstallWhatsNextXcode4 Whats next? + + There aren't any more steps required, but you might be interested in: + + - @ref Examples "More Examples" + - @ref CommandLine "Running from the Command Line" + - @ref Makefile "Install a Makefile" + + */ + +/*! + @page InstallingXcode3 Installing in Xcode 3 + + @section InstallingIOSXcode3 Installing in Xcode 3 (iOS) + + - Add a New Target. Select iOS -> Application. Name it Tests (or something similar). + - Copy and add GHUnitIOS.framework into your project: Add Files to ..., select GHUnitIOS.framework, and select the Tests target. + - Add the following frameworks to Linked Libraries: + - GHUnitIOS.framework + - CoreGraphics.framework + - Foundation.framework + - UIKit.framework + - In Build Settings, under 'Framework Search Paths' make sure the (parent) directory to GHUnitIOS.framework is listed. + - In Build Settings, under 'Other Linker Flags' in the Tests target, add -ObjC and -all_load + - By default, the Tests-Info.plist file includes MainWindow for Main nib file base name. You should clear this field. + - Add the GHUnitIOSTestMain.m (http://github.com/gabriel/gh-unit/blob/master/Project-iOS/GHUnitIOSTestMain.m) file into your project and make sure its enabled for the "Tests" target. + - (Optional) Create and and set a prefix header (Tests_Prefix.pch) and add #import to it, and then you won't have to include that import for every test. + - @ref Examples "Create a test" + - Build and run the "Tests" target. + - (Optional) @ref Makefile "Install Makefile" + + + @section InstallMacOSXXcode4 Installing in Xcode 4 (Mac OS X) + + - Add a New Target. Select Application -> Cocoa Application. Name it Tests (or something similar). + - Copy and add GHUnit.framework into your project: Add Files to 'App'..., select GHUnit.framework, and select only the "Tests" target. + - In the "Tests" target, in Build Settings, add @@loader_path/../Frameworks to Runpath Search Paths. + - In the "Tests" target, in Build Phases, select Add Build Phase and then Add Copy Files. + - Change the Destination to Frameworks. + - Drag GHUnit.framework from the project file view into the the Copy Files build phase. + - Make sure the copy phase appears before any Run Script phases. + - Copy GHUnitTestMain.m (http://github.com/gabriel/gh-unit/tree/master/Classes-MacOSX/GHUnitTestMain.m) into your project and include in the Test target. You should delete the existing main.m file (or replace the contents of the existing main.m with GHUnitTestMain.m). + - By default, the Tests-Info.plist file includes MainWindow for Main nib file base name. You should clear this field. You can also delete the existing MainMenu.xib and files like TestsAppDelegate.*. + - @ref Examples "Create a test" + - Build and run the "Tests" target. + - (Optional) @ref Makefile "Install Makefile" + + @section InstallMacOSXXcode3 Installing in Xcode 3 (Mac OS X) + + You can install it globally in /Library/Frameworks or with a little extra effort embed it with your project. + + @subsection InstallLibraryFrameworks Installing in /Library/Frameworks + + - Copy GHUnit.framework to /Library/Frameworks/ + - Add a New Target. Select Cocoa -> Application. Name it Tests (or something similar). + - In the Target 'Tests' Info window, General tab: + - Add a linked library, under Mac OS X 10.X SDK section, select GHUnit.framework + - If your main target is a library: Add a linked library, and select your main target. + - If your main target is an application, you will need to include these source files in the Test project manually. + - Add a direct dependency, and select your project. (This will cause your application or framework to build before the test target.) + - Copy GHUnitTestMain.m (http://github.com/gabriel/gh-unit/tree/master/Classes-MacOSX/GHUnitTestMain.m) into your project and include in the Test target. + - Now create a test (either by subclassing SenTestCase or GHTestCase), adding it to your test target. (See example test case below.) + - By default, the Tests-Info.plist file includes MainWindow for Main nib file base name. You should clear this field. + - @ref Examples "Create a test" + - (Optional) @ref Makefile "Install Makefile" + + @subsection InstallProject Installing in your project + + - Add a New Target. Select Cocoa -> Application. Name it Tests (or something similar). + - In the Finder, copy GHUnit.framework to your project directory (maybe in MyProject/Frameworks/.) + - In the Tests target, add the GHUnit.framework files (from MyProject/Frameworks/). It should now be visible as a Linked Framework in the target. + - In the Tests target, under Build Settings, add @loader_path/../Frameworks to Runpath Search Paths (Under All Configurations) + - In the Tests target, add New Build Phase | New Copy Files Build Phase. + - Change the Destination to Frameworks. + - Drag GHUnit.framework into the the build phase + - Make sure the copy phase appears before any Run Script phases + - Copy GHUnitTestMain.m (http://github.com/gabriel/gh-unit/tree/master/Classes-MacOSX/GHUnitTestMain.m) into your project and include in the Test target. + + - If your main target is a library: + - In the Target 'Tests' Info window, General tab: + - Add a linked library, and select your main target; This is so you can link your test target against your main target, and then you don't have to manually include source files in both targets. + - If your main target is an application, you will need to include these source files to the Test project manually. + + - Now create a test (either by subclassing SenTestCase or GHTestCase), adding it to your test target. (See example test case below.) + - By default, the Tests-Info.plist file includes MainWindow for Main nib file base name. You should clear this field. + - @ref Examples "Create a test" + - (Optional) @ref Makefile "Install Makefile" + */ + +/*! + @page Building Building + + For iOS, run make from within the Project-iOS directory. The framework is in Project-iOS/build/Framework/. + + For Mac OS X, the framework build is stored in Project/build/Release/. + */ + +/*! + @page Examples Examples + + - @ref ExampleTestCase + - @ref ExampleAsyncTestCase + + @section ExampleTestCase Example Test Case + + For example ExampleTest.m: + + @code + // For iOS + #import + // For Mac OS X + //#import + + @interface ExampleTest : GHTestCase { } + @end + + @implementation ExampleTest + + - (BOOL)shouldRunOnMainThread { + // By default NO, but if you have a UI test or test dependent on running on the main thread return YES. + // Also an async test that calls back on the main thread, you'll probably want to return YES. + return NO; + } + + - (void)setUpClass { + // Run at start of all tests in the class + } + + - (void)tearDownClass { + // Run at end of all tests in the class + } + + - (void)setUp { + // Run before each test method + } + + - (void)tearDown { + // Run after each test method + } + + - (void)testFoo { + NSString *a = @"foo"; + GHTestLog(@"I can log to the GHUnit test console: %@", a); + + // Assert a is not NULL, with no custom error description + GHAssertNotNULL(a, nil); + + // Assert equal objects, add custom error description + NSString *b = @"bar"; + GHAssertEqualObjects(a, b, @"A custom error message. a should be equal to: %@.", b); + } + + - (void)testBar { + // Another test + } + + @end + @endcode + + @section ExampleAsyncTestCase Example Async Test Case + + @code + // For iOS + #import + // For Mac OS X + //#import + + @interface ExampleAsyncTest : GHAsyncTestCase { } + @end + + @implementation ExampleAsyncTest + + - (void)testURLConnection { + + // Call prepare to setup the asynchronous action. + // This helps in cases where the action is synchronous and the + // action occurs before the wait is actually called. + [self prepare]; + + NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]]; + NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; + + // Wait until notify called for timeout (seconds); If notify is not called with kGHUnitWaitStatusSuccess then + // we will throw an error. + [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0]; + + [connection release]; + } + + - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + // Notify of success, specifying the method where wait is called. + // This prevents stray notifies from affecting other tests. + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testURLConnection)]; + } + + - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + // Notify of connection failure + [self notify:kGHUnitWaitStatusFailure forSelector:@selector(testURLConnection)]; + } + + - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + GHTestLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); + } + + @end + @endcode + + + @section ExampleProjects Example Projects + + Example projects can be found at: http://github.com/gabriel/gh-unit/tree/master/Examples/ + + */ + +/*! + @page EnvVariables Environment Variables + + @section GHUnitEnvVariables GHUnit Environment Variables + + Go into the "Get Info" contextual menu of your (Tests) executable (inside the "Executables" group in the left panel of Xcode). + Then go in the "Arguments" tab. You can add the following environment variables: + + @verbatim + GHUNIT_CLI - Default NO; Runs tests on the command line (see Debugger Console, Cmd-Shift-R) + GHUNIT_RERAISE - Default NO; If an exception is encountered it re-raises it allowing you to crash into the debugger + GHUNIT_AUTORUN - Default NO; If YES, tests will start automatically + GHUNIT_AUTOEXIT - Default NO; If YES, will exit upon test completion (no matter what); For command line MacOSX testing + @endverbatim + + + @section EnvVariablesTest Test Environment Variables (Recommended) + + Go into the "Get Info" contextual menu of your (Tests) executable (inside the "Executables" group in the left panel of Xcode). + Then go in the "Arguments" tab. You can add the following environment variables: + + @verbatim + Environment Variable: Default: Set to: + NSDebugEnabled NO YES + NSZombieEnabled NO YES + NSDeallocateZombies NO NO (or YES) + NSHangOnUncaughtException NO YES + NSAutoreleaseFreedObjectCheckEnabled NO YES + @endverbatim + + If Using NSDeallocateZombies=NO, then all objects will leak so be sure to turn it off when debugging memory leaks. + + For more info on these varaiables see NSDebug.h (http://theshadow.uw.hu/iPhoneSDKdoc/Foundation.framework/NSDebug.h.html) + + For malloc debugging: + + @verbatim + MallocStackLogging + MallocStackLoggingNoCompact + MallocScribble + MallocPreScribble + MallocGuardEdges + MallocDoNotProtectPrelude + MallocDoNotProtectPostlude + MallocCheckHeapStart + MallocCheckHeapEach + @endverbatim + + If you see a message like: + + @verbatim + 2009-10-15 13:02:24.746 Tests[38615:40b] *** -[Foo class]: message sent to deallocated instance 0x1c8e680 + @endverbatim + + Re-run (in gdb) with MallocStackLogging=YES (or MallocStackLoggingNoCompact=YES), then if you run under gdb: + + @verbatim + (gdb) shell malloc_history 38615 0x1c8e680 + + ALLOC 0x1a9ad10-0x1a9ad6f [size=96]: thread_a024a500 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __NSThreadPerformPerform | -[GHTestGroup _run:] | -[GHTest run] | +[GHTesting runTest:selector:withObject:exception:interval:] | -[Foo foo] | +[NSObject alloc] | +[NSObject allocWithZone:] | _internal_class_createInstance | _internal_class_createInstanceFromZone | calloc | malloc_zone_calloc + + @endverbatim + + Somewhere between runTest and NSObject alloc (in [Foo foo]) there may be an object that wasn't retained. 38615 is the thread id from "2009-10-15 13:02:24.746 Tests[38615:40b]", and 0x1c8e680 is the address in "message sent to deallocated instance 0x1c8e680". + + Also using MallocScribble=YES causes the malloc library to overwrite freed memory with a well-known value (0x55), and occasionally checks freed malloc blocks to make sure the memory has not been over-written overwritten written since it was cleared. + + For more info on these variables see MallocDebug (http://developer.apple.com/mac/library/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html) + + For more info on malloc_history see malloc_history (http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/malloc_history.1.html) + + */ + +/*! + + @page CommandLine Command Line + + @section CommandLineRunningTests Running from the Command Line + + To run the tests from the command line: + + - Copy the RunTests.sh (http://github.com/gabriel/gh-unit/tree/master/Scripts/RunTests.sh) file into your project in the same directory as the xcodeproj file. + + - In the Tests target, Build Phases, Select Add Build Phase + button, and select Add Run Script. + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/RunningCLI/2_add_build_phase.png + + - For the script enter: sh RunTests.sh + + @image html http://rel.me.s3.amazonaws.com/gh-unit/images/RunningCLI/3_configure_phase.png + + The path to RunTests.sh should be relative to the xcode project file (.xcodeproj). You can uncheck 'Show environment variables in build log' if you want. + + - Now run the tests From the command line: + + @verbatim + // For iOS app + GHUNIT_CLI=1 xcodebuild -target Tests -configuration Debug -sdk iphonesimulator build + + // For mac app + GHUNIT_CLI=1 xcodebuild -target Tests -configuration Debug -sdk macosx build + @endverbatim + + If you get and error like: Couldn't register Tests with the bootstrap server. it means an iPhone simulator is running and you need to close it. + + @subsection CommandLineEnv Command Line Environment + + The RunTests.sh script will only run the tests if the env variable GHUNIT_CLI is set. This is why this RunScript phase is ignored when running the test GUI. This is how we use a single Test target for both the GUI and command line testing. + + This may seem strange that we run via xcodebuild with a RunScript phase in order to work on the command line, but otherwise we may not have the environment settings or other Xcode specific configuration right. + + @section Makefile Makefile + + Follow the directions above for adding command line support. + + Example Makefile's for Mac or iPhone apps: + + - Makefile (Mac OS X): http://github.com/gabriel/gh-unit/tree/master/Project/Makefile.example (for a Mac App) + - Makefile (iOS): http://github.com/gabriel/gh-unit/tree/master/Project-iOS/Makefile.example (for an iOS App) + + The script will return a non-zero exit code on test failure. + + To run the tests via the Makefile: + + @verbatim + make test + @endverbatim + + Unfortunately, running Mac OS X from the command line isn't always supported since certain frameworks can't work + headless and will seg fault. + + @section RunningATest Running a Test Case / Single Test + + The TEST environment variable can be used to run a single test or test case. + + @verbatim + // Run all tests in GHSlowTest + make test TEST="GHSlowTest" + + // Run the method testSlowA in GHSlowTest + make test TEST="GHSlowTest/testSlowA" + @endverbatim + + */ + +/*! + + @page TestMacros Test Macros + + The following test macros are included. + + These macros are directly from: GTMSenTestCase.h (http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/UnitTesting/GTMSenTestCase.h) + prefixed with GH so as not to conflict with the GTM macros if you are using those in your project. + + The description argument appends extra information for when the assert fails; though most of the time you might leave it as nil. + + @code + GHAssertNoErr(a1, description, ...) + GHAssertErr(a1, a2, description, ...) + GHAssertNotNULL(a1, description, ...) + GHAssertNULL(a1, description, ...) + GHAssertNotEquals(a1, a2, description, ...) + GHAssertNotEqualObjects(a1, a2, desc, ...) + GHAssertOperation(a1, a2, op, description, ...) + GHAssertGreaterThan(a1, a2, description, ...) + GHAssertGreaterThanOrEqual(a1, a2, description, ...) + GHAssertLessThan(a1, a2, description, ...) + GHAssertLessThanOrEqual(a1, a2, description, ...) + GHAssertEqualStrings(a1, a2, description, ...) + GHAssertNotEqualStrings(a1, a2, description, ...) + GHAssertEqualCStrings(a1, a2, description, ...) + GHAssertNotEqualCStrings(a1, a2, description, ...) + GHAssertEqualObjects(a1, a2, description, ...) + GHAssertEquals(a1, a2, description, ...) + GHAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right)) + GHAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) + GHFail(description, ...) + GHAssertNil(a1, description, ...) + GHAssertNotNil(a1, description, ...) + GHAssertTrue(expr, description, ...) + GHAssertTrueNoThrow(expr, description, ...) + GHAssertFalse(expr, description, ...) + GHAssertFalseNoThrow(expr, description, ...) + GHAssertThrows(expr, description, ...) + GHAssertThrowsSpecific(expr, specificException, description, ...) + GHAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) + GHAssertNoThrow(expr, description, ...) + GHAssertNoThrowSpecific(expr, specificException, description, ...) + GHAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) + @endcode + + */ + +/*! + + @page Customizing Customizing + + @section CustomTests Custom Test Case Classes + + You can register additional classes at runtime; if you have your own. For example: + + @code + [[GHTesting sharedInstance] registerClassName:@"MySpecialTestCase"]; + @endcode + + @section AlternateIOSAppDelegate Using an Alternate iOS Application Delegate + + If you want to use a custom application delegate in your test environment, you should subclass GHUnitIOSAppDelegate: + + @code + @interface MyTestApplicationDelegate : GHUnitIOSAppDelegate { } + @end + @endcode + + Then in GHUnitIOSTestMain.m: + + @code + retVal = UIApplicationMain(argc, argv, nil, @"MyTestApplicationDelegate"); + @endcode + + I am looking into removing this dependency but this will work in the meantime. + + @section UsingSenTesting Using SenTestingKit + + You can also use GHUnit with SenTestCase, for example: + + @code + #import + + @interface MyTest : SenTestCase { } + @end + + @implementation MyTest + + - (void)setUp { + // Run before each test method + } + + - (void)tearDown { + // Run after each test method + } + + - (void)testFoo { + // Assert a is not NULL, with no custom error description + STAssertNotNULL(a, nil); + + // Assert equal objects, add custom error description + STAssertEqualObjects(a, b, @"Foo should be equal to: %@. Something bad happened", bar); + } + + - (void)testBar { + // Another test + } + + @end + @endcode + + */ + +/*! + + @page Hudson Hudson + + @section Using Using Hudson with GHUnit + + Hudson (http://hudson-ci.org/) is a continuous + integration server that has a broad set of support and plugins, and is easy to set up. You + can use Hudson to run your GHUnit tests after every checkin, and report the + results to your development group in a variety of ways (by email, to Campfire, + and so on). + + Here's how to set up Hudson with GHUnit. + + 1. Follow the instructions to set up a Makefile for your GHUnit project. + + 2. Download hudson.war from http://hudson-ci.org/. + Run it with java -jar hudson.war. It will start up on + http://localhost:8080/ + + 3. Go to Manage Hudson -> Manage Plugins and install whatever plugins you + need for your project. For instance, you might want to install the Git + and GitHub plugins if you host your code on GitHub (http://www.github.com) + + 4. Create a new job for your project and click on Configure. Most of the options + are self-explanatory or can be figured out with the online help. You probably + want to configure Source Code Management, and then under Build Triggers check + Poll SCM and add a schedule of * * * * * (which checks your source control + system for new changes once a minute). + + 5. Under Build, enter the following command: + + @verbatim + make clean && WRITE_JUNIT_XML=YES make test + @endverbatim + + 6. Under Post-build Actions, check Publish JUnit test result report and enter + the following in Test report XMLs: + + @verbatim + build/test-results/ *.xml (Remove the extra-space, which is there to work around doxygen bug) + @endverbatim + + That's all it takes. Check in a change that breaks one of your tests. Hudson + should detect the change, run a build and test, and then report the failure. + Fix the test, check in again, and you should see a successful build report. + + @section Troubleshooting Troubleshooting + + If your Xcode build fails with a set of font-related errors, you may be running + Hudson headless (e.g., via an SSH session). Launch Hudson via Terminal.app on + the build machine (or otherwise attach a DISPLAY to the session) in order to + address this. + + */ + \ No newline at end of file diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSAppDelegate.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSAppDelegate.h new file mode 100644 index 0000000..6f2d9ef --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSAppDelegate.h @@ -0,0 +1,39 @@ +// +// GHUnitIOSAppDelegate.h +// GHUnitIOS +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import + +@interface GHUnitIOSAppDelegate : NSObject { + UIWindow *window_; + + UINavigationController *navigationController_; +} + +@end + diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTableViewDataSource.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTableViewDataSource.h new file mode 100644 index 0000000..d2642d0 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTableViewDataSource.h @@ -0,0 +1,41 @@ +// +// GHUnitIOSTableViewDataSource.h +// GHUnitIOS +// +// Created by Gabriel Handford on 5/5/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import +#import "GHTestViewModel.h" + +@interface GHUnitIOSTableViewDataSource : GHTestViewModel { + +} + +- (GHTestNode *)nodeForIndexPath:(NSIndexPath *)indexPath; + +- (void)setSelectedForAllNodes:(BOOL)selected; + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTestViewController.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTestViewController.h new file mode 100644 index 0000000..e36d1a9 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSTestViewController.h @@ -0,0 +1,43 @@ +// +// GHUnitIOSTestViewController.h +// GHUnitIOS +// +// Created by Gabriel Handford on 2/20/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import +#import "GHTestViewModel.h" + +@interface GHUnitIOSTestViewController : UIViewController { + UITextView *textView_; + + GHTestNode *testNode_; + + GHTestRunner *runner_; +} + +- (void)setTest:(id)test; + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSView.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSView.h new file mode 100644 index 0000000..f9d7fba --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSView.h @@ -0,0 +1,55 @@ +// +// GHUnitIOSView.h +// GHUnitIOS +// +// Created by Gabriel Handford on 4/12/10. +// Copyright 2010. All rights reserved. +// +// 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. +// + +#import +#import + + +@interface GHUnitIOSView : UIView { + UISearchBar *searchBar_; + + UITableView *tableView_; + + //! Status label at bottom of the view + UILabel *statusLabel_; + + UISegmentedControl *filterControl_; + + UIToolbar *runToolbar_; + + UIView *footerView_; +} + +@property (readonly, nonatomic) UILabel *statusLabel; +@property (readonly, nonatomic) UISegmentedControl *filterControl; +@property (readonly, nonatomic) UISearchBar *searchBar; +@property (readonly, nonatomic) UITableView *tableView; + + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSViewController.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSViewController.h new file mode 100644 index 0000000..0cf698f --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIOSViewController.h @@ -0,0 +1,71 @@ +// +// GHUnitIOSViewController.h +// GHUnitIOS +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +#import "GHUnitIOSView.h" + +#import "GHUnitIOSTableViewDataSource.h" +#import "GHUnitIOSTestViewController.h" + +@interface GHUnitIOSViewController : UIViewController { + + GHUnitIOSView *view_; + + //! Data source for table view + GHUnitIOSTableViewDataSource *dataSource_; + GHTestSuite *suite_; + + UIBarButtonItem *runButton_; + + //! If set then we will no longer auto scroll as tests are run + BOOL userDidDrag_; + +} + +@property (retain, nonatomic) GHTestSuite *suite; + +- (void)reloadTest:(id)test; + +- (void)scrollToTest:(id)test; +- (void)scrollToBottom; + +- (void)setStatusText:(NSString *)message; + +- (void)runTests; + +- (void)cancel; + +- (void)reload; + +- (void)loadDefaults; +- (void)saveDefaults; + +- (GHUnitIOSTableViewDataSource *)dataSource; + +@end + diff --git a/GHUnitIOS.framework/Versions/A/Headers/GHUnitIPhoneAppDelegate.h b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIPhoneAppDelegate.h new file mode 100644 index 0000000..0e7ec81 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/GHUnitIPhoneAppDelegate.h @@ -0,0 +1,36 @@ +// +// GHUnitIPhoneAppDelegate.h +// GHUnitIOS +// +// Created by Gabriel Handford on 6/28/11. +// +// 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. +// + +#import "GHUnitIOSAppDelegate.h" + +// For backwards compatibility (see GHUnitIOSAppDelegate) +@interface GHUnitIPhoneAppDelegate : GHUnitIOSAppDelegate { + +} + +@end diff --git a/GHUnitIOS.framework/Versions/A/Headers/NSException+GHTestFailureExceptions.h b/GHUnitIOS.framework/Versions/A/Headers/NSException+GHTestFailureExceptions.h new file mode 100644 index 0000000..214bcc5 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/NSException+GHTestFailureExceptions.h @@ -0,0 +1,97 @@ +// +// NSException+GHTestFailureExceptions.h +// +// Created by Johannes Rudolph on 23.09.09. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// Copyright 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. +// + +extern NSString *const GHTestFilenameKey; +extern NSString *const GHTestLineNumberKey; +extern NSString *const GHTestFailureException; + + +// GTM_BEGIN + +#import + +@interface NSException(GHUTestFailureExceptions) ++ (NSException *)ghu_failureInFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInCondition:(NSString *)condition + isTrue:(BOOL)isTrue + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInEqualityBetweenObject:(id)left + andObject:(id)right + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInInequalityBetweenObject:(id)left + andObject:(id)right + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInEqualityBetweenValue:(NSValue *)left + andValue:(NSValue *)right + withAccuracy:(NSValue *)accuracy + inFile:(NSString *)filename + atLine:(int) ineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInRaise:(NSString *)expression + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; ++ (NSException *)ghu_failureInRaise:(NSString *)expression + exception:(NSException *)exception + inFile:(NSString *)filename + atLine:(int)lineNumber + withDescription:(NSString *)formatString, ...; +@end + +// GTM_END + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Headers/NSValue+GHValueFormatter.h b/GHUnitIOS.framework/Versions/A/Headers/NSValue+GHValueFormatter.h new file mode 100644 index 0000000..268571a --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Headers/NSValue+GHValueFormatter.h @@ -0,0 +1,71 @@ +// +// NSValue+GHValueFormatter.h +// +// Created by Johannes Rudolph on 23.9.2009. +// Copyright 2009. All rights reserved. +// +// 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. +// + +//! @cond DEV + +// +// Portions of this file fall under the following license, marked with +// SENTE_BEGIN - SENTE_END +// +// Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved. +// +// Use of this source code is governed by the following license: +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Note: this license is equivalent to the FreeBSD license. +// +// This notice may not be removed from this file. + +#import + +// SENTE_BEGIN +@interface NSValue(GHValueFormatter) +- (NSString *)ghu_contentDescription; +@end +// SENTE_END + +//! @endcond diff --git a/GHUnitIOS.framework/Versions/A/Resources/Info.plist b/GHUnitIOS.framework/Versions/A/Resources/Info.plist new file mode 100644 index 0000000..0ba43d4 --- /dev/null +++ b/GHUnitIOS.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,18 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + me.rel.ghunit + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + CFBundleVersion + $(GHUNIT_VERSION) + + diff --git a/GHUnitIOS.framework/Versions/Current b/GHUnitIOS.framework/Versions/Current new file mode 120000 index 0000000..8c7e5a6 --- /dev/null +++ b/GHUnitIOS.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Marshmallows.xcodeproj/project.pbxproj b/Marshmallows.xcodeproj/project.pbxproj index 34057ee..e087f32 100644 --- a/Marshmallows.xcodeproj/project.pbxproj +++ b/Marshmallows.xcodeproj/project.pbxproj @@ -22,11 +22,25 @@ 7BD100D714136F7500A9921B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD100B61413675100A9921B /* UIKit.framework */; }; 7BD100D814136F7500A9921B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BE32D0914132EE4008F2DEA /* Foundation.framework */; }; 7BD100D914136F7500A9921B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD100B91413675100A9921B /* CoreGraphics.framework */; }; + 7BD100DF14136F7500A9921B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7BD100DD14136F7500A9921B /* InfoPlist.strings */; }; + 7BD100E114136F7500A9921B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD100E014136F7500A9921B /* main.m */; }; + 7BD100F814136FD200A9921B /* GHUnitIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BD100F714136FD200A9921B /* GHUnitIOS.framework */; }; + 7BD100FB141370B800A9921B /* NSDateTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD100FA141370B800A9921B /* NSDateTest.m */; }; 7BE32D0A14132EE4008F2DEA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BE32D0914132EE4008F2DEA /* Foundation.framework */; }; 7BE32D6A14133618008F2DEA /* NSString+sanity.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BE32D6814133618008F2DEA /* NSString+sanity.h */; }; 7BE32D6B14133618008F2DEA /* NSString+sanity.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BE32D6914133618008F2DEA /* NSString+sanity.m */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 7B13A56B1415CDA70033DCC2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7BE32CFD14132EE3008F2DEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7BE32D0514132EE4008F2DEA; + remoteInfo = Marshmallows; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 7B2C8D7414159642004E1123 /* UIAlertView+simple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+simple.h"; sourceTree = ""; }; 7B2C8D7514159642004E1123 /* UIAlertView+simple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+simple.m"; sourceTree = ""; }; @@ -38,9 +52,15 @@ 7BD100A514134FBE00A9921B /* MMHTTPRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMHTTPRequest.m; sourceTree = ""; }; 7BD100A8141353B700A9921B /* NSDate+relative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+relative.h"; sourceTree = ""; }; 7BD100A9141353B700A9921B /* NSDate+relative.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+relative.m"; sourceTree = ""; }; - 7BD100B41413675100A9921B /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 7BD100B61413675100A9921B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 7BD100B91413675100A9921B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; + 7BD100D514136F7500A9921B /* MarshmallowsTesting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MarshmallowsTesting.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7BD100DC14136F7500A9921B /* MarshmallowsTesting-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "MarshmallowsTesting-Info.plist"; sourceTree = ""; }; + 7BD100DE14136F7500A9921B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 7BD100E014136F7500A9921B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 7BD100E214136F7500A9921B /* MarshmallowsTesting-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MarshmallowsTesting-Prefix.pch"; sourceTree = ""; }; + 7BD100F714136FD200A9921B /* GHUnitIOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = GHUnitIOS.framework; sourceTree = ""; }; + 7BD100FA141370B800A9921B /* NSDateTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDateTest.m; sourceTree = ""; }; 7BE32D0614132EE4008F2DEA /* libMarshmallows.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMarshmallows.a; sourceTree = BUILT_PRODUCTS_DIR; }; 7BE32D0914132EE4008F2DEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 7BE32D0D14132EE4008F2DEA /* Marshmallows-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Marshmallows-Prefix.pch"; sourceTree = ""; }; @@ -50,6 +70,18 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 7BD100D214136F7500A9921B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7B13A56E1415CE360033DCC2 /* libMarshmallows.a in Frameworks */, + 7BD100D714136F7500A9921B /* UIKit.framework in Frameworks */, + 7BD100D814136F7500A9921B /* Foundation.framework in Frameworks */, + 7BD100D914136F7500A9921B /* CoreGraphics.framework in Frameworks */, + 7BD100F814136FD200A9921B /* GHUnitIOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7BE32D0314132EE4008F2DEA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -61,10 +93,31 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 7BD100DA14136F7500A9921B /* MarshmallowsTesting */ = { + isa = PBXGroup; + children = ( + 7BD100FA141370B800A9921B /* NSDateTest.m */, + 7BD100DB14136F7500A9921B /* Supporting Files */, + ); + path = MarshmallowsTesting; + sourceTree = ""; + }; + 7BD100DB14136F7500A9921B /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 7BD100DC14136F7500A9921B /* MarshmallowsTesting-Info.plist */, + 7BD100DD14136F7500A9921B /* InfoPlist.strings */, + 7BD100E014136F7500A9921B /* main.m */, + 7BD100E214136F7500A9921B /* MarshmallowsTesting-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; 7BE32CFB14132EE3008F2DEA = { isa = PBXGroup; children = ( 7BE32D0B14132EE4008F2DEA /* Marshmallows */, + 7BD100DA14136F7500A9921B /* MarshmallowsTesting */, 7BE32D0814132EE4008F2DEA /* Frameworks */, 7BE32D0714132EE4008F2DEA /* Products */, ); @@ -74,6 +127,7 @@ isa = PBXGroup; children = ( 7BE32D0614132EE4008F2DEA /* libMarshmallows.a */, + 7BD100D514136F7500A9921B /* MarshmallowsTesting.app */, ); name = Products; sourceTree = ""; @@ -81,7 +135,10 @@ 7BE32D0814132EE4008F2DEA /* Frameworks */ = { isa = PBXGroup; children = ( + 7BD100F714136FD200A9921B /* GHUnitIOS.framework */, 7BE32D0914132EE4008F2DEA /* Foundation.framework */, + 7BD100B61413675100A9921B /* UIKit.framework */, + 7BD100B91413675100A9921B /* CoreGraphics.framework */, ); name = Frameworks; sourceTree = ""; @@ -135,6 +192,24 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 7BD100D414136F7500A9921B /* MarshmallowsTesting */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7BD100F414136F7500A9921B /* Build configuration list for PBXNativeTarget "MarshmallowsTesting" */; + buildPhases = ( + 7BD100D114136F7500A9921B /* Sources */, + 7BD100D214136F7500A9921B /* Frameworks */, + 7BD100D314136F7500A9921B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B13A56C1415CDA70033DCC2 /* PBXTargetDependency */, + ); + name = MarshmallowsTesting; + productName = MarshmallowsTesting; + productReference = 7BD100D514136F7500A9921B /* MarshmallowsTesting.app */; + productType = "com.apple.product-type.application"; + }; 7BE32D0514132EE4008F2DEA /* Marshmallows */ = { isa = PBXNativeTarget; buildConfigurationList = 7BE32D1314132EE4008F2DEA /* Build configuration list for PBXNativeTarget "Marshmallows" */; @@ -173,11 +248,32 @@ projectRoot = ""; targets = ( 7BE32D0514132EE4008F2DEA /* Marshmallows */, + 7BD100D414136F7500A9921B /* MarshmallowsTesting */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 7BD100D314136F7500A9921B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BD100DF14136F7500A9921B /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ + 7BD100D114136F7500A9921B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7BD100E114136F7500A9921B /* main.m in Sources */, + 7BD100FB141370B800A9921B /* NSDateTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7BE32D0214132EE4008F2DEA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -193,7 +289,71 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 7B13A56C1415CDA70033DCC2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7BE32D0514132EE4008F2DEA /* Marshmallows */; + targetProxy = 7B13A56B1415CDA70033DCC2 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 7BD100DD14136F7500A9921B /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7BD100DE14136F7500A9921B /* en */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ + 7BD100F514136F7500A9921B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", + "\"$(SRCROOT)\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MarshmallowsTesting/MarshmallowsTesting-Prefix.pch"; + INFOPLIST_FILE = "MarshmallowsTesting/MarshmallowsTesting-Info.plist"; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 7BD100F614136F7500A9921B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", + "\"$(SRCROOT)\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "MarshmallowsTesting/MarshmallowsTesting-Prefix.pch"; + INFOPLIST_FILE = "MarshmallowsTesting/MarshmallowsTesting-Info.plist"; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + OTHER_LDFLAGS = ( + "-all_load", + "-ObjC", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; 7BE32D1114132EE4008F2DEA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -269,6 +429,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 7BD100F414136F7500A9921B /* Build configuration list for PBXNativeTarget "MarshmallowsTesting" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7BD100F514136F7500A9921B /* Debug */, + 7BD100F614136F7500A9921B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 7BE32D0014132EE3008F2DEA /* Build configuration list for PBXProject "Marshmallows" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/MarshmallowsTesting/MarshmallowsTesting-Info.plist b/MarshmallowsTesting/MarshmallowsTesting-Info.plist new file mode 100644 index 0000000..14a3fe1 --- /dev/null +++ b/MarshmallowsTesting/MarshmallowsTesting-Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + net.samhuri.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/MarshmallowsTesting/MarshmallowsTesting-Prefix.pch b/MarshmallowsTesting/MarshmallowsTesting-Prefix.pch new file mode 100644 index 0000000..f393294 --- /dev/null +++ b/MarshmallowsTesting/MarshmallowsTesting-Prefix.pch @@ -0,0 +1,14 @@ +// +// Prefix header for all source files of the 'MarshmallowsTesting' target in the 'MarshmallowsTesting' project +// + +#import + +#ifndef __IPHONE_3_0 +#warning "This project uses features only available in iPhone SDK 3.0 and later." +#endif + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/MarshmallowsTesting/NSDateTest.m b/MarshmallowsTesting/NSDateTest.m new file mode 100644 index 0000000..ed0edf7 --- /dev/null +++ b/MarshmallowsTesting/NSDateTest.m @@ -0,0 +1,144 @@ +// +// NSDateTest.m +// Marshmallows +// +// Created by Sami Samhuri on 11-09-04. +// Copyright 2011 Guru Logic. All rights reserved. +// + +#import +#import "NSDate+relative.h" + +#define MINUTE 60.0 +#define HOUR (60.0 * MINUTE) +#define DAY (24.0 * HOUR) +#define WEEK (7.0 * DAY) +#define MONTH (30.0 * DAY) +#define YEAR (365.25 * DAY) + +@interface NSDateTest : GHTestCase { } +@end + +@implementation NSDateTest + +- (void) testMethodExists +{ + NSDate *date = [NSDate date]; + GHAssertTrue([date respondsToSelector: @selector(relativeToNow)], @"Extension method -[NSDate relativeToNow] not available"); +} + +- (void) testPastDates +{ + NSDate *date; + + // < 1 minute ago + date = [NSDate dateWithTimeIntervalSinceNow: -59.0]; + GHAssertEqualStrings(@"right now", [date relativeToNow], @"Incorrect relative date."); + + // < 2 minutes ago + date = [NSDate dateWithTimeIntervalSinceNow: -119.0]; + GHAssertEqualStrings(@"a minute ago", [date relativeToNow], @"Incorrect relative date."); + + // < 1 hour ago + date = [NSDate dateWithTimeIntervalSinceNow: -57 * MINUTE]; + GHAssertEqualStrings(@"57 minutes ago", [date relativeToNow], @"Incorrect relative date."); + + // < 2 hours ago + date = [NSDate dateWithTimeIntervalSinceNow: -117 * MINUTE]; + GHAssertEqualStrings(@"an hour ago", [date relativeToNow], @"Incorrect relative date."); + + // < 1 day ago + date = [NSDate dateWithTimeIntervalSinceNow: -23 * HOUR]; + GHAssertEqualStrings(@"23 hours ago", [date relativeToNow], @"Incorrect relative date."); + + // < 2 days ago + date = [NSDate dateWithTimeIntervalSinceNow: -47 * HOUR]; + GHAssertEqualStrings(@"yesterday", [date relativeToNow], @"Incorrect relative date."); + + // < 1 week ago + date = [NSDate dateWithTimeIntervalSinceNow: -6 * DAY]; + GHAssertEqualStrings(@"6 days ago", [date relativeToNow], @"Incorrect relative date."); + + // < 2 weeks ago + date = [NSDate dateWithTimeIntervalSinceNow: -13 * DAY]; + GHAssertEqualStrings(@"last week", [date relativeToNow], @"Incorrect relative date."); + + // < 4 weeks ago + date = [NSDate dateWithTimeIntervalSinceNow: -3 * WEEK]; + GHAssertEqualStrings(@"3 weeks ago", [date relativeToNow], @"Incorrect relative date."); + + // < 8 weeks ago + date = [NSDate dateWithTimeIntervalSinceNow: -7 * WEEK]; + GHAssertEqualStrings(@"last month", [date relativeToNow], @"Incorrect relative date."); + + // < 1 year ago + date = [NSDate dateWithTimeIntervalSinceNow: -11 * MONTH]; + GHAssertEqualStrings(@"11 months ago", [date relativeToNow], @"Incorrect relative date."); + + // last year + date = [NSDate dateWithTimeIntervalSinceNow: -729 * DAY]; + GHAssertEqualStrings(@"last year", [date relativeToNow], @"Incorrect relative date."); + + // 5 years ago + date = [NSDate dateWithTimeIntervalSinceNow: -5 * YEAR - 1]; + GHAssertEqualStrings(@"5 years ago", [date relativeToNow], @"Incorrect relative date."); +} + +- (void) testFutureDates +{ + NSDate *date; + + // within 1 minute + date = [NSDate dateWithTimeIntervalSinceNow: 59.0]; + GHAssertEqualStrings(@"right now", [date relativeToNow], @"Incorrect relative date."); + + // within 2 minutes + date = [NSDate dateWithTimeIntervalSinceNow: 119.0]; + GHAssertEqualStrings(@"in a minute", [date relativeToNow], @"Incorrect relative date."); + + // within 1 hour + date = [NSDate dateWithTimeIntervalSinceNow: 57 * MINUTE + 1]; + GHAssertEqualStrings(@"in 57 minutes", [date relativeToNow], @"Incorrect relative date."); + + // in an hour + date = [NSDate dateWithTimeIntervalSinceNow: 117 * MINUTE]; + GHAssertEqualStrings(@"in an hour", [date relativeToNow], @"Incorrect relative date."); + + // within 1 day + date = [NSDate dateWithTimeIntervalSinceNow: 23 * HOUR + 1]; + GHAssertEqualStrings(@"in 23 hours", [date relativeToNow], @"Incorrect relative date."); + + // tomorrow + date = [NSDate dateWithTimeIntervalSinceNow: 47 * HOUR]; + GHAssertEqualStrings(@"tomorrow", [date relativeToNow], @"Incorrect relative date."); + + // within 1 week + date = [NSDate dateWithTimeIntervalSinceNow: 6 * DAY + 1]; + GHAssertEqualStrings(@"in 6 days", [date relativeToNow], @"Incorrect relative date."); + + // next week + date = [NSDate dateWithTimeIntervalSinceNow: 13 * DAY]; + GHAssertEqualStrings(@"next week", [date relativeToNow], @"Incorrect relative date."); + + // within 4 weeks + date = [NSDate dateWithTimeIntervalSinceNow: 3 * WEEK + 1]; + GHAssertEqualStrings(@"in 3 weeks", [date relativeToNow], @"Incorrect relative date."); + + // next month + date = [NSDate dateWithTimeIntervalSinceNow: 7 * WEEK]; + GHAssertEqualStrings(@"next month", [date relativeToNow], @"Incorrect relative date."); + + // within 1 year + date = [NSDate dateWithTimeIntervalSinceNow: 11 * MONTH + 1]; + GHAssertEqualStrings(@"in 11 months", [date relativeToNow], @"Incorrect relative date."); + + // next year + date = [NSDate dateWithTimeIntervalSinceNow: 729 * DAY]; + GHAssertEqualStrings(@"next year", [date relativeToNow], @"Incorrect relative date."); + + // in year 5 years + date = [NSDate dateWithTimeIntervalSinceNow: 5 * YEAR + 1]; + GHAssertEqualStrings(@"in 5 years", [date relativeToNow], @"Incorrect relative date."); +} + +@end diff --git a/MarshmallowsTesting/en.lproj/InfoPlist.strings b/MarshmallowsTesting/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..477b28f --- /dev/null +++ b/MarshmallowsTesting/en.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/MarshmallowsTesting/main.m b/MarshmallowsTesting/main.m new file mode 100644 index 0000000..22b9d6f --- /dev/null +++ b/MarshmallowsTesting/main.m @@ -0,0 +1,17 @@ +// +// main.m +// MarshmallowsTesting +// +// Created by Sami Samhuri on 11-09-04. +// Copyright 2011 Guru Logic. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"GHUnitIPhoneAppDelegate"); + [pool release]; + return retVal; +}