xcunique 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/Guardfile +22 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +11 -0
- data/bin/xcunique +5 -0
- data/lib/json2plist/json2plist +21 -0
- data/lib/xcunique.rb +23 -0
- data/lib/xcunique/cli.rb +40 -0
- data/lib/xcunique/hash_ext.rb +25 -0
- data/lib/xcunique/helpers.rb +26 -0
- data/lib/xcunique/options.rb +68 -0
- data/lib/xcunique/parser.rb +54 -0
- data/lib/xcunique/sorter.rb +51 -0
- data/lib/xcunique/uniquifier.rb +36 -0
- data/lib/xcunique/version.rb +3 -0
- data/spec/fixtures/TestProject.json +548 -0
- data/spec/fixtures/TestProject/TestProject.xcodeproj/project.pbxproj +510 -0
- data/spec/fixtures/TestProject/TestProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/spec/fixtures/TestProject/TestProject.xcodeproj/project.xcworkspace/xcuserdata/paul.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/spec/fixtures/TestProject/TestProject.xcodeproj/xcuserdata/paul.xcuserdatad/xcschemes/TestProject.xcscheme +111 -0
- data/spec/fixtures/TestProject/TestProject.xcodeproj/xcuserdata/paul.xcuserdatad/xcschemes/xcschememanagement.plist +47 -0
- data/spec/fixtures/TestProject/TestProject/AppDelegate.swift +46 -0
- data/spec/fixtures/TestProject/TestProject/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- data/spec/fixtures/TestProject/TestProject/Base.lproj/LaunchScreen.storyboard +27 -0
- data/spec/fixtures/TestProject/TestProject/Base.lproj/Main.storyboard +26 -0
- data/spec/fixtures/TestProject/TestProject/Info.plist +47 -0
- data/spec/fixtures/TestProject/TestProject/ViewController.swift +25 -0
- data/spec/fixtures/TestProject/TestProjectTests/Info.plist +24 -0
- data/spec/fixtures/TestProject/TestProjectTests/TestProjectTests.swift +36 -0
- data/spec/fixtures/TestProject/TestProjectUITests/Info.plist +24 -0
- data/spec/fixtures/TestProject/TestProjectUITests/TestProjectUITests.swift +36 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/xcunique/hash_ext_spec.rb +36 -0
- data/spec/xcunique/helpers_spec.rb +58 -0
- data/spec/xcunique/parser_spec.rb +214 -0
- data/spec/xcunique/sorter_spec.rb +116 -0
- data/xcunique.gemspec +26 -0
- metadata +178 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3
|
+
<plist version="1.0">
|
4
|
+
<dict>
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
6
|
+
<string>en</string>
|
7
|
+
<key>CFBundleExecutable</key>
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
9
|
+
<key>CFBundleIdentifier</key>
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
12
|
+
<string>6.0</string>
|
13
|
+
<key>CFBundleName</key>
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
15
|
+
<key>CFBundlePackageType</key>
|
16
|
+
<string>BNDL</string>
|
17
|
+
<key>CFBundleShortVersionString</key>
|
18
|
+
<string>1.0</string>
|
19
|
+
<key>CFBundleSignature</key>
|
20
|
+
<string>????</string>
|
21
|
+
<key>CFBundleVersion</key>
|
22
|
+
<string>1</string>
|
23
|
+
</dict>
|
24
|
+
</plist>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
//
|
2
|
+
// TestProjectUITests.swift
|
3
|
+
// TestProjectUITests
|
4
|
+
//
|
5
|
+
// Created by Paul Samuels on 18/12/2015.
|
6
|
+
// Copyright © 2015 Paul Samuels. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
import XCTest
|
10
|
+
|
11
|
+
class TestProjectUITests: XCTestCase {
|
12
|
+
|
13
|
+
override func setUp() {
|
14
|
+
super.setUp()
|
15
|
+
|
16
|
+
// Put setup code here. This method is called before the invocation of each test method in the class.
|
17
|
+
|
18
|
+
// In UI tests it is usually best to stop immediately when a failure occurs.
|
19
|
+
continueAfterFailure = false
|
20
|
+
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
|
21
|
+
XCUIApplication().launch()
|
22
|
+
|
23
|
+
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
24
|
+
}
|
25
|
+
|
26
|
+
override func tearDown() {
|
27
|
+
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
28
|
+
super.tearDown()
|
29
|
+
}
|
30
|
+
|
31
|
+
func testExample() {
|
32
|
+
// Use recording to get started writing UI tests.
|
33
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
34
|
+
}
|
35
|
+
|
36
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
|
5
|
+
it 'performs a deep duplicate of simple types' do
|
6
|
+
input = {
|
7
|
+
"array" => [ 1, 2, 3 ],
|
8
|
+
"string" => 'value'
|
9
|
+
}
|
10
|
+
|
11
|
+
result = input.deep_dup
|
12
|
+
|
13
|
+
assert_equal input, result
|
14
|
+
refute_equal input.object_id, result.object_id
|
15
|
+
refute_equal input['array'].object_id, result['array'].object_id
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'substitutes objects that match in the substitutes hash' do
|
19
|
+
input = {
|
20
|
+
'aaaa' => [ 1, 2, 3 ],
|
21
|
+
'bbbb' => 'cccc',
|
22
|
+
'dddd' => 'eeee'
|
23
|
+
}
|
24
|
+
|
25
|
+
expected = {
|
26
|
+
'AAAA' => [ 1, 2, 3 ],
|
27
|
+
'BBBB' => 'CCCC',
|
28
|
+
'dddd' => 'eeee'
|
29
|
+
}
|
30
|
+
|
31
|
+
result = input.deep_dup(substitutions: { 'aaaa' => 'AAAA', 'bbbb' => 'BBBB', 'cccc' => 'CCCC' })
|
32
|
+
|
33
|
+
assert_equal expected, result
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Xcunique::Helpers do
|
4
|
+
|
5
|
+
it "returns an empty string if no name, path or fileRef are found" do
|
6
|
+
objects = {
|
7
|
+
'aaaa' => {}
|
8
|
+
}
|
9
|
+
|
10
|
+
assert_equal '', Xcunique::Helpers.resolve_attributes('aaaa', objects)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns the name if found on the object' do
|
14
|
+
objects = {
|
15
|
+
'aaaa' => {
|
16
|
+
'name' => 'Test'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
assert_equal "(name: 'Test')", Xcunique::Helpers.resolve_attributes('aaaa', objects)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns the path if found on the object' do
|
24
|
+
objects = {
|
25
|
+
'aaaa' => {
|
26
|
+
'path' => 'Test'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
assert_equal "(path: 'Test')", Xcunique::Helpers.resolve_attributes('aaaa', objects)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns the name and path if found on the object' do
|
34
|
+
objects = {
|
35
|
+
'aaaa' => {
|
36
|
+
'name' => 'Test',
|
37
|
+
'path' => 'Test'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
assert_equal "(name: 'Test', path: 'Test')", Xcunique::Helpers.resolve_attributes('aaaa', objects)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'resolves the fileRef if there is one' do
|
45
|
+
objects = {
|
46
|
+
'aaaa' => {
|
47
|
+
'fileRef' => 'bbbb'
|
48
|
+
},
|
49
|
+
'bbbb' => {
|
50
|
+
'name' => 'Test',
|
51
|
+
'path' => 'Test'
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
assert_equal "(name: 'Test', path: 'Test')", Xcunique::Helpers.resolve_attributes('aaaa', objects)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Xcunique::Parser do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@project = JSON.load(File.open(File.expand_path('../fixtures/TestProject.json', __dir__)))
|
7
|
+
@parser = Xcunique::Parser.new(@project)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:root_uuid) { @project['rootObject'] }
|
11
|
+
let(:main_group) { @project['objects'][root_uuid]['mainGroup'] }
|
12
|
+
|
13
|
+
it 'correctly parses files and groups' do
|
14
|
+
|
15
|
+
@parser.parse object: main_group
|
16
|
+
|
17
|
+
result = @parser.visited
|
18
|
+
|
19
|
+
expectations = {
|
20
|
+
|
21
|
+
# ├── Project
|
22
|
+
"/PBXGroup" => 'DACE56891C24A14C00E6ABB0',
|
23
|
+
|
24
|
+
# ├── TestProject
|
25
|
+
# ├── Products
|
26
|
+
# ├── TestProject
|
27
|
+
# ├── TestProjectTests
|
28
|
+
# ├── TestProjectUITests
|
29
|
+
"/PBXGroup/PBXGroup(name: 'Products')" => 'DACE56931C24A14D00E6ABB0',
|
30
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')" => 'DACE56941C24A14D00E6ABB0',
|
31
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectTests')" => 'DACE56A91C24A14D00E6ABB0',
|
32
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectUITests')" => 'DACE56B41C24A14D00E6ABB0',
|
33
|
+
|
34
|
+
# ├── TestProject
|
35
|
+
# │ ├── AppDelegate.swift
|
36
|
+
# │ ├── Assets.xcassets
|
37
|
+
# │ ├── Base.lproj
|
38
|
+
# │ │ ├── LaunchScreen.storyboard
|
39
|
+
# │ │ └── Main.storyboard
|
40
|
+
# │ ├── Info.plist
|
41
|
+
# │ └── ViewController.swift
|
42
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXFileReference(path: 'AppDelegate.swift')" => 'DACE56951C24A14D00E6ABB0',
|
43
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXFileReference(path: 'Assets.xcassets')" => 'DACE569C1C24A14D00E6ABB0',
|
44
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXVariantGroup(name: 'LaunchScreen.storyboard')" => 'DACE569E1C24A14D00E6ABB0',
|
45
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXVariantGroup(name: 'LaunchScreen.storyboard')/PBXFileReference(name: 'Base', path: 'Base.lproj/LaunchScreen.storyboard')" => 'DACE569F1C24A14D00E6ABB0',
|
46
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXVariantGroup(name: 'Main.storyboard')" => 'DACE56991C24A14D00E6ABB0',
|
47
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXVariantGroup(name: 'Main.storyboard')/PBXFileReference(name: 'Base', path: 'Base.lproj/Main.storyboard')" => 'DACE569A1C24A14D00E6ABB0',
|
48
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXFileReference(path: 'Info.plist')" => 'DACE56A11C24A14D00E6ABB0',
|
49
|
+
"/PBXGroup/PBXGroup(path: 'TestProject')/PBXFileReference(path: 'ViewController.swift')" => 'DACE56971C24A14D00E6ABB0',
|
50
|
+
|
51
|
+
# ├── TestProject
|
52
|
+
# ├── TestProjectTests
|
53
|
+
# │ ├── Info.plist
|
54
|
+
# │ └── TestProjectTests.swift
|
55
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectTests')/PBXFileReference(path: 'Info.plist')" => 'DACE56AC1C24A14D00E6ABB0',
|
56
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectTests')/PBXFileReference(path: 'TestProjectTests.swift')" => 'DACE56AA1C24A14D00E6ABB0',
|
57
|
+
|
58
|
+
# ├── TestProject
|
59
|
+
# └── TestProjectUITests
|
60
|
+
# ├── Info.plist
|
61
|
+
# └── TestProjectUITests.swift
|
62
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectUITests')/PBXFileReference(path: 'Info.plist')" => 'DACE56B71C24A14D00E6ABB0',
|
63
|
+
"/PBXGroup/PBXGroup(path: 'TestProjectUITests')/PBXFileReference(path: 'TestProjectUITests.swift')" => 'DACE56B51C24A14D00E6ABB0',
|
64
|
+
|
65
|
+
# ├── TestProject
|
66
|
+
# └── Products
|
67
|
+
# ├── TestProject.app
|
68
|
+
"/PBXGroup/PBXGroup(name: 'Products')/PBXFileReference(path: 'TestProject.app')" => 'DACE56921C24A14D00E6ABB0',
|
69
|
+
"/PBXGroup/PBXGroup(name: 'Products')/PBXFileReference(path: 'TestProjectTests.xctest')" => 'DACE56A61C24A14D00E6ABB0',
|
70
|
+
"/PBXGroup/PBXGroup(name: 'Products')/PBXFileReference(path: 'TestProjectUITests.xctest')" => 'DACE56B11C24A14D00E6ABB0',
|
71
|
+
}
|
72
|
+
|
73
|
+
expectations.each do |path, uuid|
|
74
|
+
assert_equal path, result[uuid]
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_equal [], result.keys - expectations.values
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'correctly parses the remaining project objects' do
|
82
|
+
|
83
|
+
@parser.parse(object: main_group)
|
84
|
+
files_and_groups = @parser.visited.keys
|
85
|
+
|
86
|
+
@parser.parse(object: root_uuid)
|
87
|
+
result = @parser.visited.reject { |key, _| files_and_groups.include?(key) }
|
88
|
+
|
89
|
+
expectations = {
|
90
|
+
|
91
|
+
# ├── mainGroup
|
92
|
+
"/PBXProject" => "DACE568A1C24A14C00E6ABB0",
|
93
|
+
|
94
|
+
# ├── mainGroup
|
95
|
+
# └── ProjectConfigurations
|
96
|
+
# ├── Debug
|
97
|
+
# ├── Release
|
98
|
+
"/PBXProject/XCConfigurationList" => "DACE568D1C24A14C00E6ABB0",
|
99
|
+
"/PBXProject/XCConfigurationList/XCBuildConfiguration(name: 'Debug')" => "DACE56B81C24A14D00E6ABB0",
|
100
|
+
"/PBXProject/XCConfigurationList/XCBuildConfiguration(name: 'Release')" => "DACE56B91C24A14D00E6ABB0",
|
101
|
+
|
102
|
+
# ├── mainGroup
|
103
|
+
# └── Target = TestProject
|
104
|
+
# └── Configurations
|
105
|
+
# ├── Debug
|
106
|
+
# ├── Release
|
107
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')" => "DACE56911C24A14D00E6ABB0",
|
108
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/XCConfigurationList" => "DACE56BA1C24A14D00E6ABB0",
|
109
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/XCConfigurationList/XCBuildConfiguration(name: 'Debug')" => "DACE56BB1C24A14D00E6ABB0",
|
110
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/XCConfigurationList/XCBuildConfiguration(name: 'Release')" => "DACE56BC1C24A14D00E6ABB0",
|
111
|
+
|
112
|
+
# ├── mainGroup
|
113
|
+
# └── Target = TestProject
|
114
|
+
# └── Build Sources
|
115
|
+
# ├── ViewController.swift
|
116
|
+
# ├── AppDelegate.swift
|
117
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXSourcesBuildPhase" => "DACE568E1C24A14D00E6ABB0",
|
118
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXSourcesBuildPhase/PBXBuildFile(path: 'ViewController.swift')" => "DACE56981C24A14D00E6ABB0",
|
119
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXSourcesBuildPhase/PBXBuildFile(path: 'AppDelegate.swift')" => "DACE56961C24A14D00E6ABB0",
|
120
|
+
|
121
|
+
# ├── mainGroup
|
122
|
+
# └── Target = TestProject
|
123
|
+
# └── Copy Frameworks
|
124
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXFrameworksBuildPhase" => "DACE568F1C24A14D00E6ABB0",
|
125
|
+
|
126
|
+
# ├── mainGroup
|
127
|
+
# └── Target = TestProject
|
128
|
+
# └── Copy Resources
|
129
|
+
# ├── LaunchScreen.storyboard
|
130
|
+
# ├── Assets.xcassets
|
131
|
+
# ├── Main.storyboard
|
132
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXResourcesBuildPhase" => "DACE56901C24A14D00E6ABB0",
|
133
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXResourcesBuildPhase/PBXBuildFile(name: 'LaunchScreen.storyboard')" => "DACE56A01C24A14D00E6ABB0",
|
134
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXResourcesBuildPhase/PBXBuildFile(path: 'Assets.xcassets')" => "DACE569D1C24A14D00E6ABB0",
|
135
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProject')/PBXResourcesBuildPhase/PBXBuildFile(name: 'Main.storyboard')" => "DACE569B1C24A14D00E6ABB0",
|
136
|
+
|
137
|
+
# ├── mainGroup
|
138
|
+
# └── Target = TestProjectTests
|
139
|
+
# └── Configurations
|
140
|
+
# ├── Debug
|
141
|
+
# ├── Release
|
142
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')" => "DACE56A51C24A14D00E6ABB0",
|
143
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/XCConfigurationList" => "DACE56BD1C24A14D00E6ABB0",
|
144
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/XCConfigurationList/XCBuildConfiguration(name: 'Debug')" => "DACE56BE1C24A14D00E6ABB0",
|
145
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/XCConfigurationList/XCBuildConfiguration(name: 'Release')" => "DACE56BF1C24A14D00E6ABB0",
|
146
|
+
|
147
|
+
# ├── mainGroup
|
148
|
+
# └── Target = TestProjectTests
|
149
|
+
# └── Build Sources
|
150
|
+
# ├── TestProjectTests.swift
|
151
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXSourcesBuildPhase" => "DACE56A21C24A14D00E6ABB0",
|
152
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXSourcesBuildPhase/PBXBuildFile(path: 'TestProjectTests.swift')" => "DACE56AB1C24A14D00E6ABB0",
|
153
|
+
|
154
|
+
# ├── mainGroup
|
155
|
+
# └── Target = TestProjectTests
|
156
|
+
# └── Copy Frameworks
|
157
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXFrameworksBuildPhase" => "DACE56A31C24A14D00E6ABB0",
|
158
|
+
|
159
|
+
# ├── mainGroup
|
160
|
+
# └── Target = TestProjectTests
|
161
|
+
# └── Copy Resources
|
162
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXResourcesBuildPhase" => "DACE56A41C24A14D00E6ABB0",
|
163
|
+
|
164
|
+
# ├── mainGroup
|
165
|
+
# └── Target = TestProjectTests
|
166
|
+
# └── Dependencies
|
167
|
+
# ├── TestProject
|
168
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXTargetDependency" => "DACE56A81C24A14D00E6ABB0",
|
169
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectTests')/PBXTargetDependency/PBXContainerItemProxy" => "DACE56A71C24A14D00E6ABB0",
|
170
|
+
|
171
|
+
# ├── mainGroup
|
172
|
+
# └── Target = TestProjectUITests
|
173
|
+
# └── Configurations
|
174
|
+
# ├── Debug
|
175
|
+
# ├── Release
|
176
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')" => "DACE56B01C24A14D00E6ABB0",
|
177
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/XCConfigurationList" => "DACE56C01C24A14D00E6ABB0",
|
178
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/XCConfigurationList/XCBuildConfiguration(name: 'Debug')" => "DACE56C11C24A14D00E6ABB0",
|
179
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/XCConfigurationList/XCBuildConfiguration(name: 'Release')" => "DACE56C21C24A14D00E6ABB0",
|
180
|
+
|
181
|
+
# ├── mainGroup
|
182
|
+
# └── Target = TestProjectUITests
|
183
|
+
# └── Build Sources
|
184
|
+
# ├── TestProjectUITests.swift
|
185
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXSourcesBuildPhase" => "DACE56AD1C24A14D00E6ABB0",
|
186
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXSourcesBuildPhase/PBXBuildFile(path: 'TestProjectUITests.swift')" => "DACE56B61C24A14D00E6ABB0",
|
187
|
+
|
188
|
+
# ├── mainGroup
|
189
|
+
# └── Target = TestProjectUITests
|
190
|
+
# └── Copy Frameworks
|
191
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXFrameworksBuildPhase" => "DACE56AE1C24A14D00E6ABB0",
|
192
|
+
|
193
|
+
# ├── mainGroup
|
194
|
+
# └── Target = TestProjectUITests
|
195
|
+
# └── Copy Resources
|
196
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXResourcesBuildPhase" => "DACE56AF1C24A14D00E6ABB0",
|
197
|
+
|
198
|
+
# ├── mainGroup
|
199
|
+
# └── Target = TestProjectUITests
|
200
|
+
# └── Dependencies
|
201
|
+
# ├── TestProject
|
202
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXTargetDependency" => "DACE56B31C24A14D00E6ABB0",
|
203
|
+
"/PBXProject/PBXNativeTarget(name: 'TestProjectUITests')/PBXTargetDependency/PBXContainerItemProxy" => "DACE56B21C24A14D00E6ABB0"
|
204
|
+
}
|
205
|
+
|
206
|
+
expectations.each do |path, uuid|
|
207
|
+
assert_equal path, result[uuid]
|
208
|
+
end
|
209
|
+
|
210
|
+
assert_equal [], result.keys - expectations.values
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Xcunique::Sorter do
|
4
|
+
|
5
|
+
describe "when sorting groups" do
|
6
|
+
it "sorts alphabetically by their name" do
|
7
|
+
project = {
|
8
|
+
'objects' => {
|
9
|
+
'PARENT' => { 'children' => [ 'groupB', 'groupA' ] },
|
10
|
+
'groupA' => { 'name' => 'A' },
|
11
|
+
'groupB' => { 'name' => 'B' }
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
result = Xcunique::Sorter.new(project).sort
|
16
|
+
|
17
|
+
assert_equal [ 'groupA', 'groupB' ], result['objects']['PARENT']['children']
|
18
|
+
end
|
19
|
+
|
20
|
+
it "sorts alphabetically by their path" do
|
21
|
+
project = {
|
22
|
+
'objects' => {
|
23
|
+
'PARENT' => { 'children' => [ 'groupB', 'groupA' ] },
|
24
|
+
'groupA' => { 'path' => 'A' },
|
25
|
+
'groupB' => { 'path' => 'B' }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
result = Xcunique::Sorter.new(project).sort
|
30
|
+
|
31
|
+
assert_equal [ 'groupA', 'groupB' ], result['objects']['PARENT']['children']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "sorts alphabetically by their name then path" do
|
35
|
+
project = {
|
36
|
+
'objects' => {
|
37
|
+
'PARENT' => { 'children' => [ 'groupB', 'groupA' ] },
|
38
|
+
'groupA' => { 'name' => 'A', 'path' => 'B' },
|
39
|
+
'groupB' => { 'name' => 'B', 'path' => 'A' }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
result = Xcunique::Sorter.new(project).sort
|
44
|
+
|
45
|
+
assert_equal [ 'groupA', 'groupB' ], result['objects']['PARENT']['children']
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "when sorting files" do
|
50
|
+
it "sorts alphabetically by their name" do
|
51
|
+
project = {
|
52
|
+
'objects' => {
|
53
|
+
'PARENT' => { 'files' => [ 'buildFileB', 'buildFileA' ] },
|
54
|
+
'buildFileA' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileA' },
|
55
|
+
'buildFileB' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileB' },
|
56
|
+
'fileA' => { 'name' => 'a.swift' },
|
57
|
+
'fileB' => { 'name' => 'b.swift' }
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
result = Xcunique::Sorter.new(project).sort
|
62
|
+
|
63
|
+
assert_equal [ 'buildFileA', 'buildFileB' ], result['objects']['PARENT']['files']
|
64
|
+
end
|
65
|
+
|
66
|
+
it "sorts alphabetically by their path" do
|
67
|
+
project = {
|
68
|
+
'objects' => {
|
69
|
+
'PARENT' => { 'files' => [ 'buildFileB', 'buildFileA' ] },
|
70
|
+
'buildFileA' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileA' },
|
71
|
+
'buildFileB' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileB' },
|
72
|
+
'fileA' => { 'path' => 'a.swift' },
|
73
|
+
'fileB' => { 'path' => 'b.swift' }
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
result = Xcunique::Sorter.new(project).sort
|
78
|
+
|
79
|
+
assert_equal [ 'buildFileA', 'buildFileB' ], result['objects']['PARENT']['files']
|
80
|
+
end
|
81
|
+
|
82
|
+
it "sorts alphabetically by their name then path" do
|
83
|
+
project = {
|
84
|
+
'objects' => {
|
85
|
+
'PARENT' => { 'files' => [ 'buildFileB', 'buildFileA' ] },
|
86
|
+
'buildFileA' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileA' },
|
87
|
+
'buildFileB' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileB' },
|
88
|
+
'fileA' => { 'name' => 'a.swift', 'path' => 'b/a.swift' },
|
89
|
+
'fileB' => { 'name' => 'b.swift', 'path' => 'a/b.swift' }
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
result = Xcunique::Sorter.new(project).sort
|
94
|
+
|
95
|
+
assert_equal [ 'buildFileA', 'buildFileB' ], result['objects']['PARENT']['files']
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "when sorting groups and files" do
|
100
|
+
it "sorts groups before files" do
|
101
|
+
project = {
|
102
|
+
'objects' => {
|
103
|
+
'PARENT' => { 'children' => [ 'buildFileA', 'groupA' ] },
|
104
|
+
'buildFileA' => { 'isa' => 'PBXBuildFile', 'fileRef' => 'fileA' },
|
105
|
+
'groupA' => { 'isa' => 'PBXGroup', 'name' => 'a' },
|
106
|
+
'fileA' => { 'name' => 'a' },
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
result = Xcunique::Sorter.new(project).sort
|
111
|
+
|
112
|
+
assert_equal [ 'groupA', 'buildFileA' ], result['objects']['PARENT']['children']
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|