iut 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/bin/iut +2 -0
- data/iut.gemspec +24 -0
- data/lib/iut.rb +17 -0
- data/lib/iut/generator.rb +28 -0
- data/lib/iut/version.rb +4 -0
- data/template/project/iUnitTest/iUnitTest.xcodeproj/project.pbxproj +480 -0
- data/template/project/iUnitTest/iUnitTest/Classes/.do_not_remove_this_directory +0 -0
- data/template/project/iUnitTest/iUnitTest/Tests/.do_not_remove_this_directory +0 -0
- data/template/project/iUnitTest/iUnitTest/en.lproj/InfoPlist.strings +2 -0
- data/template/project/iUnitTest/iUnitTest/iUnitTest-Info.plist +44 -0
- data/template/project/iUnitTest/iUnitTest/iUnitTest-Prefix.pch +14 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/Default.png +0 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/IUTAppDelegate.h +20 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/IUTAppDelegate.m +38 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/IUTDetailView.xib +184 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/IUTMainWindow.xib +732 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/IUTTestView.xib +432 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/Settings.bundle/Japanese.lproj/Root.strings +0 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/Settings.bundle/Root.plist +39 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/Settings.bundle/en.lproj/Root.strings +0 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/AppAgent.h +33 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/AppAgent.m +135 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/AppAgentHelper.h +63 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UINavigationBarBasedTest.h +25 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UINavigationBarBasedTest.m +49 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITabBarAndNavigationBarBasedTest.h +23 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITabBarAndNavigationBarBasedTest.m +42 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITabBarBasedTest.h +25 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITabBarBasedTest.m +50 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITableViewBasedTest.h +23 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITableViewBasedTest.m +57 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITableViewControllerTest.h +22 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UITableViewControllerTest.m +44 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UIViewBasedTest.h +21 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UIViewBasedTest.m +52 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UIViewControllerTest.h +63 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/ControllerTest/UIViewControllerTest.m +162 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/GTMSenTestCase.h +17 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/GTMSenTestCase.m +15 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTAssertion.h +135 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTAssertion.m +216 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTAssertionInfo.h +60 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTAssertionInfo.m +104 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTDetailViewController.h +24 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTDetailViewController.m +81 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTLog.h +14 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTPreference.h +34 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTPreference.m +125 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTResultTableViewCell.h +27 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTResultTableViewCell.m +83 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTResultTableViewController.h +26 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTResultTableViewController.m +193 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTest.h +74 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTest.m +127 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTestRunner.h +66 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTestRunner.m +449 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTestRunnerViewController.h +59 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/IUTTestRunnerViewController.m +163 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/NSExceptionExtension.h +21 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/NSExceptionExtension.m +52 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/SenTestAssertion.h +82 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/SourceCodeOpener.h +65 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/SourceCodeOpener.m +176 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/UnitTest/UITableViewControllerTestHelper.h +35 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/isd_logo_60x40.png +0 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/isd_logo_60x40_w.png +0 -0
- data/template/project/iUnitTest/iUnitTest/iunittest/iunittest_icon.png +0 -0
- data/template/project/iUnitTest/iUnitTest/main.m +18 -0
- data/template/project/iUnitTest/script/sync_source.rb +27 -0
- metadata +119 -0
@@ -0,0 +1,163 @@
|
|
1
|
+
//
|
2
|
+
// IUTTestRunnerViewController.m
|
3
|
+
// iUnitTest
|
4
|
+
//
|
5
|
+
// Created by Katsuyoshi Ito on 09/01/16.
|
6
|
+
// Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import "IUTTestRunnerViewController.h"
|
10
|
+
#import "IUTTestRunner.h"
|
11
|
+
#import "IUTPreference.h"
|
12
|
+
|
13
|
+
|
14
|
+
@interface IUTTestRunnerViewController(_private)
|
15
|
+
- (void)updateControls;
|
16
|
+
@end
|
17
|
+
|
18
|
+
@implementation IUTTestRunnerViewController
|
19
|
+
|
20
|
+
@synthesize progressView, startStopButton, indicatorView, resultLabel, resultTestViewController, allButton;
|
21
|
+
@synthesize running, runner;
|
22
|
+
|
23
|
+
|
24
|
+
/*
|
25
|
+
// The designated initializer. Override to perform setup that is required before the view is loaded.
|
26
|
+
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
27
|
+
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
|
28
|
+
// Custom initialization
|
29
|
+
}
|
30
|
+
return self;
|
31
|
+
}
|
32
|
+
*/
|
33
|
+
|
34
|
+
/*
|
35
|
+
// Implement loadView to create a view hierarchy programmatically, without using a nib.
|
36
|
+
- (void)loadView {
|
37
|
+
}
|
38
|
+
*/
|
39
|
+
|
40
|
+
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
|
41
|
+
- (void)viewDidLoad {
|
42
|
+
[super viewDidLoad];
|
43
|
+
|
44
|
+
runner = [IUTTestRunner new];
|
45
|
+
|
46
|
+
indicatorView.hidesWhenStopped = YES;
|
47
|
+
[self updateControls];
|
48
|
+
[progressView setProgress:0.0];
|
49
|
+
|
50
|
+
resultTestViewController = [[IUTResultTableViewController alloc] initWithStyle:UITableViewStylePlain];
|
51
|
+
resultTestViewController.view.frame = CGRectMake(0, 50, 320, 410 - 42);
|
52
|
+
resultTestViewController.view.backgroundColor = [UIColor clearColor];
|
53
|
+
resultTestViewController.navigationController = self.navigationController;
|
54
|
+
resultTestViewController.runner = self.runner;
|
55
|
+
[self.view addSubview:resultTestViewController.view];
|
56
|
+
[[UIApplication sharedApplication].keyWindow bringSubviewToFront:resultTestViewController.view];
|
57
|
+
[resultTestViewController.tableView reloadData];
|
58
|
+
|
59
|
+
if ([[IUTPreference sharedPreference]isAutoRun]) {
|
60
|
+
[self startAction:self];
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
/*
|
65
|
+
// Override to allow orientations other than the default portrait orientation.
|
66
|
+
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
67
|
+
// Return YES for supported orientations
|
68
|
+
return (interfaceOrientation == UIInterfaceOrientationPortrait);
|
69
|
+
}
|
70
|
+
*/
|
71
|
+
|
72
|
+
- (void)didReceiveMemoryWarning {
|
73
|
+
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
|
74
|
+
// Release anything that's not essential, such as cached data
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
- (void)dealloc {
|
79
|
+
[resultTestViewController release];
|
80
|
+
[progressView release];
|
81
|
+
[startStopButton release];
|
82
|
+
[indicatorView release];
|
83
|
+
[resultLabel release];
|
84
|
+
[allButton release];
|
85
|
+
[runner release];
|
86
|
+
[super dealloc];
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
- (void)updateControls
|
91
|
+
{
|
92
|
+
if (self.isRunning) {
|
93
|
+
[self setButtonTitle:@"Stop"];
|
94
|
+
[progressView setProgress:0.0];
|
95
|
+
[indicatorView startAnimating];
|
96
|
+
[resultLabel setText:@""];
|
97
|
+
} else {
|
98
|
+
[self setButtonTitle:@"Start"];
|
99
|
+
[indicatorView stopAnimating];
|
100
|
+
[resultLabel setText:runner.result];
|
101
|
+
}
|
102
|
+
[resultTestViewController.tableView reloadData];
|
103
|
+
self.view.backgroundColor = runner.backgroundColor;
|
104
|
+
|
105
|
+
allButton.enabled = !self.isRunning && [[IUTPreference sharedPreference] canClear];
|
106
|
+
}
|
107
|
+
|
108
|
+
- (IBAction)startStopAction:(id)sender
|
109
|
+
{
|
110
|
+
if (self.isRunning) {
|
111
|
+
[self stopAction:(id)sender];
|
112
|
+
} else {
|
113
|
+
[self startAction:(id)sender];
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
|
118
|
+
- (IBAction)startAction:(id)sender
|
119
|
+
{
|
120
|
+
self.running = YES;
|
121
|
+
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self.runner withObject:self];
|
122
|
+
}
|
123
|
+
|
124
|
+
- (IBAction)stopAction:(id)sender
|
125
|
+
{
|
126
|
+
self.running = NO;
|
127
|
+
[self.runner stop:self];
|
128
|
+
}
|
129
|
+
|
130
|
+
- (IBAction)clearPassedTestsAction:(id)sender
|
131
|
+
{
|
132
|
+
[[IUTPreference sharedPreference] clearPassedTests];
|
133
|
+
[self updateControls];
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
- (void)setButtonTitle:(NSString *)title
|
138
|
+
{
|
139
|
+
[startStopButton setTitle:title forState:UIControlStateNormal];
|
140
|
+
[startStopButton setTitle:title forState:UIControlStateHighlighted];
|
141
|
+
[startStopButton setTitle:title forState:UIControlStateDisabled];
|
142
|
+
}
|
143
|
+
|
144
|
+
- (void)setProgress:(NSNumber *)value
|
145
|
+
{
|
146
|
+
[progressView setProgress:[value floatValue]];
|
147
|
+
}
|
148
|
+
|
149
|
+
- (void)willTest:(id)sender
|
150
|
+
{
|
151
|
+
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
|
152
|
+
[self updateControls];
|
153
|
+
}
|
154
|
+
|
155
|
+
- (void)didTest:(id)sender
|
156
|
+
{
|
157
|
+
[self stopAction:self];
|
158
|
+
[self updateControls];
|
159
|
+
[UIApplication sharedApplication].applicationIconBadgeNumber = self.runner.badgeNumber;
|
160
|
+
}
|
161
|
+
|
162
|
+
|
163
|
+
@end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
//
|
2
|
+
// NSExceptionExtension.h
|
3
|
+
// iUnitTest
|
4
|
+
//
|
5
|
+
// Created by Katsuyoshi Ito on 09/05/14.
|
6
|
+
// Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import <UIKit/UIKit.h>
|
10
|
+
#import "IUTAssertionInfo.h"
|
11
|
+
|
12
|
+
|
13
|
+
@interface NSException(IUTAssertionInfo)
|
14
|
+
@property (assign, readonly) IUTAssertionInfo *assertionInfo;
|
15
|
+
@property (readonly) BOOL isFailure;
|
16
|
+
@property (readonly) BOOL isError;
|
17
|
+
@end
|
18
|
+
|
19
|
+
@interface NSException(IUTResultTableViewCell)
|
20
|
+
- (UIColor *)color;
|
21
|
+
@end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
//
|
2
|
+
// NSExceptionExtension.m
|
3
|
+
// iUnitTest
|
4
|
+
//
|
5
|
+
// Created by Katsuyoshi Ito on 09/05/14.
|
6
|
+
// Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import "NSExceptionExtension.h"
|
10
|
+
#import "IUTAssertion.h"
|
11
|
+
#import "IUTTestRunner.h"
|
12
|
+
|
13
|
+
|
14
|
+
@implementation NSException(IUTAssertionInfo)
|
15
|
+
|
16
|
+
- (IUTAssertionInfo *)assertionInfo
|
17
|
+
{
|
18
|
+
if ([self isFailure] || [self isError]) {
|
19
|
+
return [[self userInfo] objectForKey:IUTAssertionInfoKey];
|
20
|
+
}
|
21
|
+
return nil;
|
22
|
+
}
|
23
|
+
|
24
|
+
- (BOOL)isFailure
|
25
|
+
{
|
26
|
+
return [[self name] isEqualToString:IUTAssertionExceptionName];
|
27
|
+
}
|
28
|
+
|
29
|
+
- (BOOL)isError
|
30
|
+
{
|
31
|
+
return [[self name] isEqualToString:IUTAssertionErrorExceptionName];
|
32
|
+
}
|
33
|
+
|
34
|
+
@end
|
35
|
+
|
36
|
+
@implementation NSException(IUTResultTableViewCell)
|
37
|
+
|
38
|
+
- (UIColor *)color
|
39
|
+
{
|
40
|
+
IUTAssertionInfo *info = self.assertionInfo;
|
41
|
+
|
42
|
+
if ([self isFailure]) {
|
43
|
+
return [info.methodName isEqualToString:@"testThisClassAlways"] ? [IUTTestRunner failureColor2] : [IUTTestRunner failureColor];
|
44
|
+
} else
|
45
|
+
if ([self isError]) {
|
46
|
+
return [IUTTestRunner errorColor];
|
47
|
+
}
|
48
|
+
return nil;
|
49
|
+
}
|
50
|
+
|
51
|
+
@end
|
52
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
/*
|
2
|
+
* SenTestAssertion.h
|
3
|
+
* iUnitTest
|
4
|
+
*
|
5
|
+
* Created by Katsuyoshi Ito on 09/02/03.
|
6
|
+
* Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
|
10
|
+
#define STAssertNil(a1, description, ...) \
|
11
|
+
ASSERT_NIL(a1)
|
12
|
+
|
13
|
+
#define STAssertNotNil(a1, description, ...) \
|
14
|
+
ASSERT_NOT_NIL(a1)
|
15
|
+
|
16
|
+
#define STAssertTrue(expression, description, ...) \
|
17
|
+
ASSERT(expression)
|
18
|
+
|
19
|
+
#define STAssertFalse(expression, description, ...) \
|
20
|
+
ASSERT(!expression)
|
21
|
+
|
22
|
+
#define STAssertEqualObjects(a1, a2, description, ...) \
|
23
|
+
ASSERT_EQUAL(a1, a2)
|
24
|
+
|
25
|
+
#define STAssertEquals(a1, a2, description, ...) \
|
26
|
+
{ \
|
27
|
+
char *e = @encode(__typeof(a1)); \
|
28
|
+
if (*e == 'i') { \
|
29
|
+
ASSERT_EQUAL_INT((a1), (int)(a2)); \
|
30
|
+
} \
|
31
|
+
else \
|
32
|
+
if (*e == 'f') { \
|
33
|
+
ASSERT_EQUAL_FLOAT((a1), (float)(a2)); \
|
34
|
+
} \
|
35
|
+
else \
|
36
|
+
if (*e == 'd') { \
|
37
|
+
ASSERT_EQUAL_DOUBLE((a1), (double)(a2)); \
|
38
|
+
} else { \
|
39
|
+
ASSERT_FAIL(@"not supported in this case."); \
|
40
|
+
} \
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
#define STAssertEqualsWithAccuracy(left, right, accuracy, description, ...) \
|
45
|
+
{ \
|
46
|
+
char *e = @encode(__typeof(left)); \
|
47
|
+
if (*e == 'f') { \
|
48
|
+
ASSERT_EQUAL_FLOAT_DELTA((left), (float)(right), (float)(accuracy)); \
|
49
|
+
} \
|
50
|
+
else \
|
51
|
+
if (*e == 'd') { \
|
52
|
+
ASSERT_EQUAL_DOUBLE_DELTA((left), (double)(right), (double)(accuracy)); \
|
53
|
+
} else { \
|
54
|
+
ASSERT_FAIL(@"not supported in this case."); \
|
55
|
+
} \
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
#define STAssertThrows(expression, description, ...) \
|
60
|
+
ASSERT_RAISE(expression)
|
61
|
+
|
62
|
+
/* FIXME: not suuported
|
63
|
+
#define STAssertThrowsSpecific(expression, specificException, description, ...) \
|
64
|
+
#define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \
|
65
|
+
*/
|
66
|
+
|
67
|
+
#define STAssertNoThrow(expression, description, ...) \
|
68
|
+
ASSERT_NOTHING_RAISED(expression)
|
69
|
+
|
70
|
+
/* FIXME: not suuported
|
71
|
+
#define STAssertNoThrowSpecific(expression, specificException, description, ...) \
|
72
|
+
#define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \
|
73
|
+
*/
|
74
|
+
|
75
|
+
#define STFail(description, ...) \
|
76
|
+
ASSERT_FAIL(([NSString stringWithFormat:description, ##__VA_ARGS__]))
|
77
|
+
|
78
|
+
|
79
|
+
/* FIXME: not suuported
|
80
|
+
#define STAssertTrueNoThrow(expression, description, ...) \
|
81
|
+
#define STAssertFalseNoThrow(expression, description, ...) \
|
82
|
+
*/
|
@@ -0,0 +1,65 @@
|
|
1
|
+
//
|
2
|
+
// SourceCodeOpener.h
|
3
|
+
// iUnitTestTest
|
4
|
+
//
|
5
|
+
// Created by Katsuyoshi Ito on 09/04/26.
|
6
|
+
// Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import <Foundation/Foundation.h>
|
10
|
+
|
11
|
+
|
12
|
+
#if TARGET_IPHONE_SIMULATOR
|
13
|
+
|
14
|
+
#define SOURCE_CODE_OPENER_START() [SourceCodeOpener sourceCodeOpener]
|
15
|
+
#define SOURCE_CODE_OPENER_OPEN_HERE() [[SourceCodeOpener sourceCodeOpener] open:[NSString stringWithFormat:@"%s", __FILE__] line:__LINE__]
|
16
|
+
|
17
|
+
#else
|
18
|
+
|
19
|
+
#define SOURCE_CODE_OPENER_START()
|
20
|
+
#define SOURCE_CODE_OPENER_OPEN_HERE()
|
21
|
+
|
22
|
+
#endif
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
#if TARGET_IPHONE_SIMULATOR
|
27
|
+
|
28
|
+
@interface SourceCodeOpener : NSObject <NSNetServiceDelegate, NSNetServiceBrowserDelegate> {
|
29
|
+
|
30
|
+
NSNetServiceBrowser *browser;
|
31
|
+
NSMutableSet *services;
|
32
|
+
NSNetService *targetService;
|
33
|
+
NSMutableSet *resolvingServices;
|
34
|
+
NSFileHandle *fileHandle;
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
@property (retain) NSNetService *targetService;
|
39
|
+
@property (retain) NSFileHandle *fileHandle;
|
40
|
+
|
41
|
+
|
42
|
+
+ (id)sourceCodeOpener;
|
43
|
+
|
44
|
+
|
45
|
+
#pragma mark -
|
46
|
+
#pragma mark NSNetServiceBrowser's delegate
|
47
|
+
|
48
|
+
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing;
|
49
|
+
|
50
|
+
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing;
|
51
|
+
|
52
|
+
|
53
|
+
#pragma mark -
|
54
|
+
#pragma mark NSNetService's delegate
|
55
|
+
|
56
|
+
- (void)netServiceDidResolveAddress:(NSNetService *)sender;
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
- (void)open:(NSString *)filePath line:(NSInteger)line;
|
61
|
+
|
62
|
+
|
63
|
+
@end
|
64
|
+
|
65
|
+
#endif
|
@@ -0,0 +1,176 @@
|
|
1
|
+
//
|
2
|
+
// SourceCodeOpener.m
|
3
|
+
// iUnitTestTest
|
4
|
+
//
|
5
|
+
// Created by Katsuyoshi Ito on 09/04/26.
|
6
|
+
// Copyright 2009 ITO SOFT DESIGN Inc. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
|
10
|
+
#if TARGET_IPHONE_SIMULATOR
|
11
|
+
|
12
|
+
|
13
|
+
#import "SourceCodeOpener.h"
|
14
|
+
#import <sys/types.h>
|
15
|
+
#import <sys/socket.h>
|
16
|
+
#import <netinet/in.h>
|
17
|
+
#import <arpa/inet.h>
|
18
|
+
#import <unistd.h>
|
19
|
+
|
20
|
+
|
21
|
+
@interface SourceCodeOpener(_private)
|
22
|
+
- (BOOL)openWithSocketAddress:(struct sockaddr *)socketAddress;
|
23
|
+
- (void)close;
|
24
|
+
- (BOOL)isOpend;
|
25
|
+
@end
|
26
|
+
|
27
|
+
|
28
|
+
@implementation SourceCodeOpener
|
29
|
+
|
30
|
+
@synthesize targetService, fileHandle;
|
31
|
+
|
32
|
+
+ (id)sourceCodeOpener
|
33
|
+
{
|
34
|
+
static id opener = nil;
|
35
|
+
if (opener == nil) {
|
36
|
+
opener = [self new];
|
37
|
+
}
|
38
|
+
return opener;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
- (id)init
|
44
|
+
{
|
45
|
+
self = [super init];
|
46
|
+
if (self) {
|
47
|
+
browser = [NSNetServiceBrowser new];
|
48
|
+
services = [NSMutableSet new];
|
49
|
+
resolvingServices = [NSMutableSet new];
|
50
|
+
[browser setDelegate:self];
|
51
|
+
[browser searchForServicesOfType:@"_iunittest_opencode._tcp." inDomain:@""];
|
52
|
+
}
|
53
|
+
return self;
|
54
|
+
}
|
55
|
+
|
56
|
+
- (void)dealloc
|
57
|
+
{
|
58
|
+
[self close];
|
59
|
+
for (NSNetService *service in [resolvingServices allObjects]) {
|
60
|
+
[service stop];
|
61
|
+
}
|
62
|
+
[resolvingServices release];
|
63
|
+
[services release];
|
64
|
+
[super dealloc];
|
65
|
+
}
|
66
|
+
|
67
|
+
#pragma mark -
|
68
|
+
#pragma mark open/close
|
69
|
+
|
70
|
+
- (BOOL)openWithSocketAddress:(struct sockaddr *)socketAddress
|
71
|
+
{
|
72
|
+
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
|
73
|
+
if (socket_fd != -1) {
|
74
|
+
self.fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:socket_fd closeOnDealloc:YES];
|
75
|
+
int len = sizeof(*socketAddress);
|
76
|
+
int result = connect(socket_fd, socketAddress, len);
|
77
|
+
if (result != -1) {
|
78
|
+
return YES;
|
79
|
+
} else {
|
80
|
+
[self close];
|
81
|
+
}
|
82
|
+
} else {
|
83
|
+
[self close];
|
84
|
+
}
|
85
|
+
return NO;
|
86
|
+
}
|
87
|
+
|
88
|
+
- (void)close
|
89
|
+
{
|
90
|
+
if (self.fileHandle) {
|
91
|
+
self.fileHandle = nil;
|
92
|
+
self.targetService = nil;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
- (BOOL)isOpend
|
97
|
+
{
|
98
|
+
return self.fileHandle ? YES : NO;
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
#pragma mark -
|
103
|
+
#pragma mark NSNetServiceBrowser's delegate
|
104
|
+
|
105
|
+
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing
|
106
|
+
{
|
107
|
+
[services addObject:netService];
|
108
|
+
[resolvingServices addObject:netService];
|
109
|
+
[netService setDelegate:self];
|
110
|
+
[netService resolveWithTimeout:1.0];
|
111
|
+
}
|
112
|
+
|
113
|
+
- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing
|
114
|
+
{
|
115
|
+
if ([resolvingServices containsObject:netService]) {
|
116
|
+
[netService stop];
|
117
|
+
[resolvingServices removeObject:netService];
|
118
|
+
}
|
119
|
+
[services removeObject:netService];
|
120
|
+
}
|
121
|
+
|
122
|
+
#pragma mark -
|
123
|
+
#pragma mark NSNetService's delegate
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
- (void)netServiceDidResolveAddress:(NSNetService *)sender
|
128
|
+
{
|
129
|
+
[resolvingServices removeObject:sender];
|
130
|
+
|
131
|
+
if (![self isOpend]) {
|
132
|
+
// to make local domain
|
133
|
+
NSString *hostName = [[NSProcessInfo processInfo] hostName];
|
134
|
+
hostName = [[[hostName componentsSeparatedByString:@"."] objectAtIndex:0] stringByAppendingString:@".local."];
|
135
|
+
if ([[sender hostName] caseInsensitiveCompare:hostName] == NSOrderedSame) {
|
136
|
+
|
137
|
+
if ([[sender addresses] count] > 0) {
|
138
|
+
NSData * address;
|
139
|
+
struct sockaddr *socketAddress;
|
140
|
+
int i;
|
141
|
+
BOOL gotAddress = NO;
|
142
|
+
|
143
|
+
for (i = 0; i < [[sender addresses] count]; i++) {
|
144
|
+
address = [[sender addresses] objectAtIndex:i];
|
145
|
+
socketAddress = (struct sockaddr *)[address bytes];
|
146
|
+
|
147
|
+
if (socketAddress->sa_family == AF_INET) {
|
148
|
+
gotAddress = YES;
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
if (gotAddress) {
|
153
|
+
if ([self openWithSocketAddress:socketAddress]) {
|
154
|
+
self.targetService = sender;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
- (void)open:(NSString *)filePath line:(NSInteger)line
|
165
|
+
{
|
166
|
+
if ([self isOpend]) {
|
167
|
+
if (line) {
|
168
|
+
NSString *cmd = [NSString stringWithFormat:@"%@:%d\n", filePath, line];
|
169
|
+
[self.fileHandle writeData:[cmd dataUsingEncoding:NSUTF8StringEncoding]];
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
@end
|
175
|
+
|
176
|
+
#endif
|