iut 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|