-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSenTestTool.m
171 lines (144 loc) · 5.66 KB
/
SenTestTool.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//*$Id: SenTestTool.m,v 1.11 2005/04/02 03:18:24 phink Exp $*/
// Copyright (c) 1997-2003 Sente SA. All rights reserved.
//
// 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 "SenTestTool.h"
static NSString *SenTestedUnitPath = @"SenTestedUnitPath";
static NSString *SenTestScopeKey = @"SenTest";
static NSString *SenTestDefaultScope = @"Self";
// Copied from SenFoundation to make otest independant of SenFoundation.
@interface NSMutableArray (OtestAddition)
- (void) setValue:(NSString *) aValue forArgumentName:(NSString *) aKey;
@end
@implementation NSMutableArray (SenTaskAddition)
- (void) setValue:(NSString *) aValue forArgumentName:(NSString *) aKey
{
NSString *defaultKey = [NSString stringWithFormat:@"-%@", aKey];
unsigned int anIndex = [self indexOfObject:defaultKey];
if (anIndex == NSNotFound) {
[self addObject:defaultKey];
[self addObject:aValue];
}
else {
[self replaceObjectAtIndex:(anIndex + 1) withObject:aValue];
}
}
@end
@implementation SenTestTool
+ (void) initialize
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *registeredDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
SenTestDefaultScope, SenTestScopeKey,
nil];
[defaults registerDefaults:registeredDefaults];
}
+ (SenTestTool *) sharedInstance
{
static id instance = nil;
if (instance == nil) {
instance = [[self alloc] init];
}
return instance;
}
- (void) showUsage
{
NSLog (@"Usage: %@ [-SenTest Self | All | None | <TestCaseClassName/testMethodName>] <path of unit to be tested>",
[[NSProcessInfo processInfo] processName]);
}
- (NSBundle *) bundleWithPath:(NSString *) aPath
{
if ([[NSFileManager defaultManager] fileExistsAtPath:aPath]) {
return [NSBundle bundleWithPath:aPath];
}
return nil;
}
- (BOOL) runTestFromBundle:(NSBundle *) aBundle
{
BOOL result = NO;
[[NSUserDefaults standardUserDefaults] setObject:[aBundle bundlePath] forKey:SenTestedUnitPath];
result = [aBundle load];
if (result) {
// The bundle has been loaded, and it should be linked against SenTestingKit.
// so SenTestProbe should be available
// (but we do not want to link otest with SenTestingKit to be able to test the kit itself.)
id testProbeClass = NSClassFromString (@"SenTestProbe");
if (testProbeClass != nil) {
[testProbeClass performSelector:@selector(runTests:) withObject:nil];
}
}
return result;
}
- (void) launchTaskFromPath:(NSString *) aPath bundle:(NSBundle *) aBundle
{
NSString *testedUnitPath;
NSString *launchPath;
NSMutableArray *arguments = [NSMutableArray arrayWithArray:[[NSProcessInfo processInfo] arguments]];
[arguments setValue:[[NSUserDefaults standardUserDefaults] stringForKey:SenTestScopeKey] forArgumentName:SenTestScopeKey];
if (aBundle != nil) {
testedUnitPath = aPath;
launchPath = [aBundle executablePath];
}
else {
// FIXME: This is a hack based on the fact that [NSBundle bundleForClass:aClass] returns a bundle with
// the tool parent folder as its path.
testedUnitPath = [aPath stringByDeletingLastPathComponent];
launchPath = aPath;
}
[arguments setValue:testedUnitPath forArgumentName:SenTestedUnitPath];
[[NSTask launchedTaskWithLaunchPath:launchPath arguments:arguments] waitUntilExit];
}
- (void) run
{
NS_DURING
if ([[[NSProcessInfo processInfo] arguments] count] < 2) {
[NSException raise:NSInvalidArgumentException format:@"Missing arguments"];
}
else {
NSString *path = [[[NSProcessInfo processInfo] arguments] lastObject];
NSBundle *bundle = [self bundleWithPath:path];
if (bundle != nil) {
if (![self runTestFromBundle:bundle]) {
[self launchTaskFromPath:path bundle:bundle];
}
}
else {
[self launchTaskFromPath:path bundle:nil];
}
}
NS_HANDLER
[self showUsage];
NSLog (@"%@", localException);
NS_ENDHANDLER
}
+ (void) run
{
[[self sharedInstance] run];
}
@end