Skip to content

Commit 0e37e11

Browse files
authored
Merge pull request #39 from surfstudio/template-fixes
Template fixes for version 2.0
2 parents f08bacc + c78bc3d commit 0e37e11

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1591
-116
lines changed

Surf Application Unit Test Base.xctemplate/TemplateInfo.plist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<array>
2424
<string>Tests/.gitkeep</string>
2525
<string>Resources/.gitkeep</string>
26+
<string>../XCTestCase.swift</string>
2627
</array>
2728
<key>Definitions</key>
2829
<dict>
@@ -48,6 +49,11 @@
4849
<key>TargetIndices</key>
4950
<array/>
5051
</dict>
52+
<key>../XCTestCase.swift</key>
53+
<dict>
54+
<key>Path</key>
55+
<string>XCTestCase.swift</string>
56+
</dict>
5157
</dict>
5258
</dict>
5359
</plist>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// ___COPYRIGHT___
3+
//
4+
5+
import XCTest
6+
7+
private class Weak<T: AnyObject> {
8+
weak var value: T?
9+
init (value: T) {
10+
self.value = value
11+
}
12+
}
13+
14+
extension XCTestCase {
15+
16+
/// Verifies whether the given constructed UIViewController and its dependencies
17+
/// get deallocated after being presented and dismissed.
18+
///
19+
/// - Parameter objects: Сonstructor to use for creating the view controller and its dependencies.
20+
func assertDeallocation(of objects: () -> (UIViewController, [AnyObject])) {
21+
// Box for the view controller
22+
weak var weakReferenceViewController: UIViewController?
23+
// Box for dependecies
24+
var weakReferenceDependencies: [Weak<AnyObject>] = []
25+
26+
let autoreleasepoolExpectation = expectation(description: "Autoreleasepool should drain")
27+
28+
autoreleasepool {
29+
let rootViewController = UIViewController()
30+
31+
// Make sure that the view is active and we can use it for presenting views.
32+
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
33+
window.rootViewController = rootViewController
34+
window.makeKeyAndVisible()
35+
36+
let (testedViewController, dependencies) = objects()
37+
38+
/// Present and dismiss the view after which the view controller should be released.
39+
rootViewController.present(
40+
testedViewController,
41+
animated: false,
42+
completion: {
43+
// Set presented controller to box
44+
weakReferenceViewController = rootViewController.presentedViewController
45+
// Set dependencies to box
46+
dependencies.forEach {
47+
weakReferenceDependencies.append(Weak(value: $0))
48+
}
49+
// Check that none of them are deallocated
50+
XCTAssertNotNil(weakReferenceViewController)
51+
weakReferenceDependencies.forEach {
52+
XCTAssertNotNil($0)
53+
}
54+
rootViewController.dismiss(
55+
animated: false,
56+
completion: {
57+
autoreleasepoolExpectation.fulfill()
58+
}
59+
)
60+
}
61+
)
62+
}
63+
wait(for: [autoreleasepoolExpectation], timeout: 5.0)
64+
wait(
65+
for: weakReferenceViewController == nil,
66+
timeout: 3.0,
67+
description: "The view controller should be deallocated since no strong reference points to it."
68+
)
69+
wait(
70+
for: weakReferenceDependencies.filter { $0.value != nil }.isEmpty,
71+
timeout: 3.0,
72+
description: "Dependencies of the controller should be deallocated since no strong reference points to it."
73+
)
74+
}
75+
76+
/// Checks for the callback to be the expected value within the given timeout.
77+
///
78+
/// - Parameters:
79+
/// - condition: The condition to check for.
80+
/// - timeout: The timeout in which the callback should return true.
81+
/// - description: A string to display in the test log for this expectation, to help diagnose failures.
82+
func wait(for condition: @autoclosure @escaping () -> Bool,
83+
timeout: TimeInterval,
84+
description: String,
85+
file: StaticString = #file,
86+
line: UInt = #line) {
87+
let end = Date().addingTimeInterval(timeout)
88+
89+
var value: Bool = false
90+
let closure: () -> Void = {
91+
value = condition()
92+
}
93+
94+
while !value && 0 < end.timeIntervalSinceNow {
95+
if RunLoop.current.run(mode: RunLoop.Mode.default, before: Date(timeIntervalSinceNow: 0.002)) {
96+
Thread.sleep(forTimeInterval: 0.002)
97+
}
98+
closure()
99+
}
100+
101+
closure()
102+
103+
XCTAssertTrue(
104+
value,
105+
"➡️🚨 Timed out waiting for condition to be true: \"\(description)\"",
106+
file: file,
107+
line: line
108+
)
109+
}
110+
111+
}
112+
113+
extension XCTestCase {
114+
115+
func expectationWithDescription(_ description: String,
116+
timeout: TimeInterval,
117+
performBlock:(_ expectation: XCTestExpectation) -> Void) {
118+
let expectation = self.expectation(description: description)
119+
performBlock(expectation)
120+
waitForExpectations(timeout: timeout, handler: nil)
121+
}
122+
123+
}

Surf Base Application.xctemplate/.gitignore

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ build/
1212
xcuserdata
1313
*.xccheckout
1414
*.moved-aside
15-
DerivedData
15+
DerivedData/
1616
*.hmap
1717
*.ipa
1818
*.xcuserstate
@@ -25,7 +25,8 @@ DerivedData
2525
# you should judge for yourself, the pros and cons are mentioned at:
2626
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
2727
#
28-
# Pods/
28+
Podfile.lock
29+
Pods/
2930

3031
# Exported environment variables for XcodeCoverage
3132
env.sh
@@ -39,7 +40,11 @@ fastlane/test_output
3940
fastlane/Provisioning
4041
fastlane/Build
4142
fastlane/report.xml
43+
buildData
4244

4345
# Bundler
4446
.bundle/
45-
Gemfile.lock
47+
Gemfile.lock
48+
49+
# Generamba
50+
Templates/

Surf Base Application.xctemplate/AppDelegate.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
//
2-
// ___FILENAME___
3-
// ___PACKAGENAME___
4-
//
5-
// Created by ___FULLUSERNAME___ on ___DATE___.
6-
//___COPYRIGHT___
2+
// ___COPYRIGHT___
73
//
84

95
import UIKit
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1-
platform :ios, '10.0'
1+
platform :ios, '11.0'
22

3+
use_frameworks!
34
inhibit_all_warnings!
45

56
def utils
67
pod 'SwiftGen', '~> 6.1.0'
78
pod 'SwiftLint', '~> 0.30.1'
89
end
910

11+
def surf_utils
12+
# Put needed utils from SurfUtils here
13+
end
14+
15+
def surf_lib
16+
pod 'PluggableApplicationDelegate', :git => 'https://github.com/surfstudio/PluggableApplicationDelegate.git', :commit => 'b24aabe3f34d51072cee5cac3b576dbb1f4ca9ec'
17+
# And other Surf pods, like NodeKit
18+
end
19+
1020
def common_pods
1121
utils
22+
surf_utils
23+
surf_lib
24+
1225
# Put your pods here
1326
end
1427

1528
target '___PACKAGENAME___' do
16-
use_frameworks!
1729
common_pods
1830
end

Surf Base Application.xctemplate/TemplateInfo.plist

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@
278278
<key>Nodes</key>
279279
<array>
280280
<string>../fastlane</string>
281+
<string>../ci</string>
281282
<string>../Podfile</string>
282283
<string>../.gitignore</string>
283284
<string>Third Party/.gitkeep</string>
284285
<string>Services/.gitkeep</string>
285-
<string>User Stories/.gitkeep</string>
286286
<string>Resources/Strings/.gitkeep</string>
287287
<string>Resources/Images/.gitkeep</string>
288288
<string>Resources/Constants/.gitkeep</string>
@@ -294,6 +294,7 @@
294294
<string>Library/Extensions/.gitkeep</string>
295295
<string>Library/Reusable Layer/.gitkeep</string>
296296
<string>Library/Protocols/.gitkeep</string>
297+
<string>Library/Routers/.gitkeep</string>
297298
<string>Application/LaunchScreen.xib</string>
298299
<string>Info.plist:iPhone</string>
299300
<string>Info.plist:UIRequiredDeviceCapabilities:base</string>
@@ -310,6 +311,15 @@
310311
<string>Non-iOS Resources</string>
311312
</array>
312313
</dict>
314+
<key>../ci</key>
315+
<dict>
316+
<key>Path</key>
317+
<string>ci</string>
318+
<key>Group</key>
319+
<array>
320+
<string>Non-iOS Resources</string>
321+
</array>
322+
</dict>
313323
<key>../Podfile</key>
314324
<dict>
315325
<key>Path</key>
@@ -386,6 +396,18 @@
386396
<key>TargetIndices</key>
387397
<array/>
388398
</dict>
399+
<key>Library/Routers/.gitkeep</key>
400+
<dict>
401+
<key>Group</key>
402+
<array>
403+
<string>Library</string>
404+
<string>Routers</string>
405+
</array>
406+
<key>Path</key>
407+
<string>.gitkeep</string>
408+
<key>TargetIndices</key>
409+
<array/>
410+
</dict>
389411
<key>Models/Entity/.gitkeep</key>
390412
<dict>
391413
<key>Group</key>
@@ -458,15 +480,6 @@
458480
<key>TargetIndices</key>
459481
<array/>
460482
</dict>
461-
<key>User Stories/.gitkeep</key>
462-
<dict>
463-
<key>Group</key>
464-
<string>User Stories</string>
465-
<key>Path</key>
466-
<string>../.gitkeep</string>
467-
<key>TargetIndices</key>
468-
<array/>
469-
</dict>
470483
<key>Services/.gitkeep</key>
471484
<dict>
472485
<key>Group</key>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@Library('surf-lib@version-1.0.0-SNAPSHOT') // https://bitbucket.org/surfstudio/jenkins-pipeline-lib/
2+
import ru.surfstudio.ci.pipeline.pr.PrPipelineiOS
3+
import ru.surfstudio.ci.stage.StageStrategy
4+
import ru.surfstudio.ci.CommonUtil
5+
6+
//init
7+
def pipeline = new PrPipelineiOS(this)
8+
pipeline.init()
9+
10+
//customization
11+
pipeline.getStage(pipeline.UNIT_TEST).body = {
12+
CommonUtil.shWithRuby(this, "make test")
13+
junit 'fastlane/test_output/report.junit'
14+
archiveArtifacts artifacts: 'fastlane/test_output/report.html'
15+
}
16+
pipeline.getStage(pipeline.UNIT_TEST).strategy = StageStrategy.FAIL_WHEN_STAGE_ERROR
17+
pipeline.getStage(pipeline.INSTRUMENTATION_TEST).strategy = StageStrategy.SKIP_STAGE
18+
19+
//run
20+
pipeline.run()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@Library('surf-lib@version-1.0.0-SNAPSHOT') // https://bitbucket.org/surfstudio/jenkins-pipeline-lib/
2+
import ru.surfstudio.ci.pipeline.tag.TagPipelineiOS
3+
import ru.surfstudio.ci.stage.StageStrategy
4+
5+
//init
6+
def pipeline = new TagPipelineiOS(this)
7+
pipeline.init()
8+
9+
//customization
10+
pipeline.getStage(pipeline.BUILD).strategy = StageStrategy.SKIP_STAGE
11+
pipeline.getStage(pipeline.UNIT_TEST).strategy = StageStrategy.SKIP_STAGE
12+
pipeline.getStage(pipeline.INSTRUMENTATION_TEST).strategy = StageStrategy.SKIP_STAGE
13+
pipeline.getStage(pipeline.STATIC_CODE_ANALYSIS).strategy = StageStrategy.SKIP_STAGE
14+
15+
//run
16+
pipeline.run()

0 commit comments

Comments
 (0)