zerg_xcode 0.1 → 0.2
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/CHANGELOG +2 -0
- data/Manifest +9 -0
- data/RUBYFORGE +2 -2
- data/lib/zerg_xcode/objects/pbx_container_item_proxy.rb +10 -0
- data/lib/zerg_xcode/objects/pbx_group.rb +3 -0
- data/lib/zerg_xcode/objects/pbx_project.rb +11 -0
- data/lib/zerg_xcode/objects/pbx_target_dependency.rb +7 -0
- data/lib/zerg_xcode/objects/xc_configuration_list.rb +3 -0
- data/lib/zerg_xcode/objects/xcode_object.rb +16 -2
- data/lib/zerg_xcode/plugins/import.rb +306 -1
- data/lib/zerg_xcode.rb +4 -0
- data/test/objects/pbx_container_item_proxy_test.rb +14 -0
- data/test/objects/pbx_group_test.rb +12 -0
- data/test/objects/pbx_project_test.rb +12 -0
- data/test/objects/pbx_target_dependency_test.rb +14 -0
- data/test/objects/xc_configuration_list_test.rb +12 -0
- data/test/objects/xcode_object_test.rb +26 -0
- data/test/plugins/import_test.rb +211 -2
- data/testdata/FlatTestApp/FlatTestApp.xcodeproj/project.pbxproj +332 -0
- data/testdata/ZergSupport.xcodeproj/project.pbxproj +33 -52
- data/zerg_xcode.gemspec +5 -5
- metadata +19 -2
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -6,8 +6,12 @@ lib/zerg_xcode/file_format/lexer.rb
|
|
6
6
|
lib/zerg_xcode/file_format/parser.rb
|
7
7
|
lib/zerg_xcode/file_format/paths.rb
|
8
8
|
lib/zerg_xcode/objects/pbx_build_file.rb
|
9
|
+
lib/zerg_xcode/objects/pbx_container_item_proxy.rb
|
10
|
+
lib/zerg_xcode/objects/pbx_group.rb
|
9
11
|
lib/zerg_xcode/objects/pbx_native_target.rb
|
10
12
|
lib/zerg_xcode/objects/pbx_project.rb
|
13
|
+
lib/zerg_xcode/objects/pbx_target_dependency.rb
|
14
|
+
lib/zerg_xcode/objects/xc_configuration_list.rb
|
11
15
|
lib/zerg_xcode/objects/xcode_object.rb
|
12
16
|
lib/zerg_xcode/plugins/core/core.rb
|
13
17
|
lib/zerg_xcode/plugins/help.rb
|
@@ -28,8 +32,12 @@ test/file_format/lexer_test.rb
|
|
28
32
|
test/file_format/parser_test.rb
|
29
33
|
test/file_format/path_test.rb
|
30
34
|
test/objects/pbx_build_file_test.rb
|
35
|
+
test/objects/pbx_container_item_proxy_test.rb
|
36
|
+
test/objects/pbx_group_test.rb
|
31
37
|
test/objects/pbx_native_target_test.rb
|
32
38
|
test/objects/pbx_project_test.rb
|
39
|
+
test/objects/pbx_target_dependency_test.rb
|
40
|
+
test/objects/xc_configuration_list_test.rb
|
33
41
|
test/objects/xcode_object_test.rb
|
34
42
|
test/plugins/core/core_test.rb
|
35
43
|
test/plugins/import_test.rb
|
@@ -38,6 +46,7 @@ test/plugins/ls_test.rb
|
|
38
46
|
test/plugins/retarget_test.rb
|
39
47
|
test/plugins/test_helper.rb
|
40
48
|
test/shortcuts_test.rb
|
49
|
+
testdata/FlatTestApp/FlatTestApp.xcodeproj/project.pbxproj
|
41
50
|
testdata/project.pbxproj
|
42
51
|
testdata/project.pbxproj.compat
|
43
52
|
testdata/TestApp/TestApp.xcodeproj/project.pbxproj
|
data/RUBYFORGE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Quickstart for Rubyforge:
|
2
2
|
|
3
|
-
1)
|
3
|
+
1) Get the code
|
4
4
|
git clone git@github.com:costan/zerg_xcode.git
|
5
5
|
|
6
6
|
2) Install the rubyforge gem
|
@@ -30,7 +30,7 @@ Releasing a new gemspec to Github
|
|
30
30
|
rake package
|
31
31
|
|
32
32
|
2) Copy the spec
|
33
|
-
cp pkg/zerg_xcode
|
33
|
+
cp pkg/zerg_xcode-*/zerg_xcode.gemspec .
|
34
34
|
|
35
35
|
3) Commit the spec
|
36
36
|
git add zerg_xcode.gemspec
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Proxy for another object.
|
2
|
+
#
|
3
|
+
# Unsure these are useful, since each object has an unique ID. They are probably
|
4
|
+
# implementation artifacts.
|
5
|
+
class ZergXcode::Objects::PBXContainerItemProxy < ZergXcode::XcodeObject
|
6
|
+
# The proxied object.
|
7
|
+
def target
|
8
|
+
self['remoteGlobalIDString']
|
9
|
+
end
|
10
|
+
end
|
@@ -3,12 +3,23 @@ class ZergXcode::Objects::PBXProject < ZergXcode::XcodeObject
|
|
3
3
|
# Used to implement save!
|
4
4
|
attr_accessor :source_filename
|
5
5
|
|
6
|
+
# :nodoc: override to copy the new metadata
|
7
|
+
def copy_metadata(source)
|
8
|
+
super
|
9
|
+
self.source_filename = source.source_filename
|
10
|
+
end
|
11
|
+
|
6
12
|
# Saves a project that was loaded by ZergXcode.load
|
7
13
|
def save!
|
8
14
|
raise 'Project not loaded by ZergXcode.load' unless @source_filename
|
9
15
|
ZergXcode.dump self, @source_filename
|
10
16
|
end
|
11
17
|
|
18
|
+
# The root path of the project.
|
19
|
+
def root_path
|
20
|
+
ZergXcode::Paths.project_root_at source_filename
|
21
|
+
end
|
22
|
+
|
12
23
|
# All the files referenced by the project.
|
13
24
|
def all_files
|
14
25
|
files = []
|
@@ -71,6 +71,16 @@ class ZergXcode::XcodeObject
|
|
71
71
|
visit_hash(@attrs, &accept)
|
72
72
|
self
|
73
73
|
end
|
74
|
+
|
75
|
+
# Convenience method mapping over visit and exploring each object once.
|
76
|
+
def visit_once(&accept)
|
77
|
+
visited = Set.new([self])
|
78
|
+
self.visit do |object, parent, key, value|
|
79
|
+
visited << object
|
80
|
+
next_value = yield object, parent, key, value
|
81
|
+
visited.include?(value) ? false : next_value
|
82
|
+
end
|
83
|
+
end
|
74
84
|
|
75
85
|
def visit_hash(hash, &accept)
|
76
86
|
hash.each_key do |key|
|
@@ -137,8 +147,12 @@ class ZergXcode::XcodeObject
|
|
137
147
|
|
138
148
|
def shallow_copy
|
139
149
|
new_object = self.class.new @attrs.dup
|
140
|
-
new_object.
|
150
|
+
new_object.copy_metadata self
|
141
151
|
return new_object
|
142
|
-
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def copy_metadata(source)
|
155
|
+
self.archive_id, self.version = source.archive_id, source.version
|
156
|
+
end
|
143
157
|
end
|
144
158
|
|
@@ -1,4 +1,9 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
|
1
4
|
class ZergXcode::Plugins::Import
|
5
|
+
include ZergXcode::Objects
|
6
|
+
|
2
7
|
def help
|
3
8
|
{:short => 'imports the objects from a project into another project',
|
4
9
|
:long => <<"END" }
|
@@ -14,6 +19,306 @@ END
|
|
14
19
|
source = ZergXcode.load args.shift
|
15
20
|
target = ZergXcode.load(args.shift || '.')
|
16
21
|
|
17
|
-
|
22
|
+
file_ops = import_project! source, target
|
23
|
+
target.save!
|
24
|
+
execute_file_ops! file_ops
|
25
|
+
end
|
26
|
+
|
27
|
+
# Executes the given file operations.
|
28
|
+
def execute_file_ops!(file_ops)
|
29
|
+
file_ops.each do |op|
|
30
|
+
case op[:op]
|
31
|
+
when :delete
|
32
|
+
FileUtils.rm_r op[:path] if File.exist? op[:path]
|
33
|
+
when :copy
|
34
|
+
target_dir = File.dirname op[:to]
|
35
|
+
FileUtils.mkdir_p target_dir unless File.exist? target_dir
|
36
|
+
if File.exist? op[:from]
|
37
|
+
FileUtils.cp_r op[:from], op[:to]
|
38
|
+
else
|
39
|
+
print "Source does not have file #{op[:from]}\n"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Imports the objects of the source project into the target project.
|
46
|
+
#
|
47
|
+
# Attempts to preserve reference integrity in the target project, as follows.
|
48
|
+
# If the source objects have counterparts in the target, their contents is
|
49
|
+
# merged into the target project's objects.
|
50
|
+
#
|
51
|
+
# Returns an array of file operations that need to be performed to migrate the
|
52
|
+
# files associated with the two projects.
|
53
|
+
#
|
54
|
+
# The target project is modified in place.
|
55
|
+
def import_project!(source, target)
|
56
|
+
old_target_paths = target.all_files.map { |file| file[:path] }
|
57
|
+
|
58
|
+
# duplicate the source, because the duplicate's object graph will be warped
|
59
|
+
scrap_source = ZergXcode::XcodeObject.from source
|
60
|
+
|
61
|
+
mappings = cross_reference scrap_source, target
|
62
|
+
bins = bin_mappings mappings, scrap_source
|
63
|
+
|
64
|
+
# special case for merging targets
|
65
|
+
map! scrap_source, mappings
|
66
|
+
merge! scrap_source['targets'], target['targets']
|
67
|
+
|
68
|
+
# merge the object graphs
|
69
|
+
bins[:merge].each do |object|
|
70
|
+
map! object, mappings
|
71
|
+
merge! object, mappings[object]
|
72
|
+
end
|
73
|
+
bins[:overwrite].each do |object|
|
74
|
+
map! object, mappings
|
75
|
+
overwrite! object, mappings[object]
|
76
|
+
end
|
77
|
+
|
78
|
+
# make sure all the mappings point in the right place
|
79
|
+
target.visit_once do |object, parent, key, value|
|
80
|
+
if mappings[value]
|
81
|
+
next mappings[value]
|
82
|
+
else
|
83
|
+
next true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
new_target_paths = target.all_files.map { |file| file[:path] }
|
88
|
+
source_paths = source.all_files.map { |file| file[:path] }
|
89
|
+
return compute_deletes(target.root_path, old_target_paths,
|
90
|
+
new_target_paths) +
|
91
|
+
compute_copies(source.root_path, source_paths, target.root_path)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Computes the file delete operations in a merge.
|
95
|
+
#
|
96
|
+
# Deletes all the files that aren't in the target project anymore.
|
97
|
+
def compute_deletes(root, old_paths, new_paths)
|
98
|
+
new_path_set = Set.new(new_paths)
|
99
|
+
old_paths.select { |path| path[0, 2] == './' }.
|
100
|
+
reject { |path| new_path_set.include? path }.
|
101
|
+
map { |path| { :op => :delete, :path => clean_join(root, path) } }
|
102
|
+
end
|
103
|
+
|
104
|
+
# Computes the file copy operations in a merge.
|
105
|
+
#
|
106
|
+
# Copies all the files from the source project assuming they received the same
|
107
|
+
# path in the target project. The assumption is correct if source was imported
|
108
|
+
# into target.
|
109
|
+
def compute_copies(source_root, source_paths, target_root)
|
110
|
+
source_paths.select { |path| path[0, 2] == './' }.map do |path|
|
111
|
+
{ :op => :copy, :from => clean_join(source_root, path),
|
112
|
+
:to => clean_join(target_root, path) }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def clean_join(root, path)
|
117
|
+
Pathname.new(File.join(root, path)).cleanpath.to_s
|
118
|
+
end
|
119
|
+
|
120
|
+
# Bins merge mappings for a project into mappings to be merged and mappings to
|
121
|
+
# be overwritten.
|
122
|
+
def bin_mappings(mappings, source)
|
123
|
+
merge_set = Set.new
|
124
|
+
overwrite_set = Set.new
|
125
|
+
|
126
|
+
# the project's top-level attributes are always merged
|
127
|
+
source.attrs.each do |attr|
|
128
|
+
merge_set << source[attr] if mappings[source[attr]]
|
129
|
+
end
|
130
|
+
|
131
|
+
mappings.each do |source_object, target_object|
|
132
|
+
next if source_object == target_object
|
133
|
+
next if merge_set.include? source_object
|
134
|
+
|
135
|
+
if source_object.kind_of?(PBXGroup) && source_object['path'].nil?
|
136
|
+
merge_set << source_object
|
137
|
+
elsif source_object.kind_of? XCConfigurationList
|
138
|
+
merge_set << source_object
|
139
|
+
else
|
140
|
+
overwrite_set << source_object
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
overwrite_set.delete source
|
145
|
+
{ :merge => merge_set, :overwrite => overwrite_set }
|
146
|
+
end
|
147
|
+
|
148
|
+
# Modifies an object's attributes according to the given mappings.
|
149
|
+
# This explores the object graph, but does not go into sub-objects.
|
150
|
+
def map!(object, mappings)
|
151
|
+
object.visit_once do |object, parent, key, value|
|
152
|
+
if mappings[value]
|
153
|
+
parent[key] = mappings[value]
|
154
|
+
next false
|
155
|
+
end
|
156
|
+
next true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Merges the contents of a source object into the target object.
|
161
|
+
#
|
162
|
+
# Warning: the target will share internal objects with the source. This is
|
163
|
+
# intended to be used in a bigger-level opration, where the source will be
|
164
|
+
# thrown away afterwards.
|
165
|
+
def merge!(source, target)
|
166
|
+
if source.class != target.class
|
167
|
+
raise "Attempting to merge-combine different kinds of objects - " +
|
168
|
+
"#{source.class} != #{target.class}"
|
169
|
+
end
|
170
|
+
|
171
|
+
case source
|
172
|
+
when ZergXcode::XcodeObject
|
173
|
+
merge! source._attr_hash, target._attr_hash
|
174
|
+
when Hash
|
175
|
+
source.each_key do |key|
|
176
|
+
if !target.has_key?(key)
|
177
|
+
target[key] = source[key]
|
178
|
+
elsif source[key].kind_of? ZergXcode::XcodeObject
|
179
|
+
target[key] = source[key]
|
180
|
+
elsif source[key].kind_of?(String)
|
181
|
+
target[key] = source[key]
|
182
|
+
elsif !source[key].kind_of?(Enumerable)
|
183
|
+
target[key] = source[key]
|
184
|
+
else
|
185
|
+
merge! source[key], target[key]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
when Enumerable
|
189
|
+
target_set = Set.new(target.to_a)
|
190
|
+
source.each do |value|
|
191
|
+
next if target_set.include? value
|
192
|
+
target << value
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Overwrites the contents of the target object with the source object.
|
198
|
+
#
|
199
|
+
# Warning: the target will share internal objects with the source. This is
|
200
|
+
# intended to be used in a bigger-level opration, where the source will be
|
201
|
+
# thrown away afterwards.
|
202
|
+
def overwrite!(source, target)
|
203
|
+
if source.class != target.class
|
204
|
+
raise "Attempting to overwrite-combine different kinds of objects - " +
|
205
|
+
"#{source.class} != #{target.class}"
|
206
|
+
end
|
207
|
+
|
208
|
+
case source
|
209
|
+
when ZergXcode::XcodeObject
|
210
|
+
overwrite! source._attr_hash, target._attr_hash
|
211
|
+
when Hash
|
212
|
+
target.clear
|
213
|
+
target.merge! source
|
214
|
+
when Enumerable
|
215
|
+
target.clear
|
216
|
+
source.each { |value| target << value }
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Cross-references the objects in two object graphs that are to be merged.
|
221
|
+
# Returns a Hash associating objects in both the source and the target object
|
222
|
+
# graphs with the corresponding objects in the
|
223
|
+
def cross_reference(source, target, mappings = {})
|
224
|
+
if source.class != target.class
|
225
|
+
raise "Attempting to cross-reference different kinds of objects - " +
|
226
|
+
"#{source.class} != #{target.class}"
|
227
|
+
end
|
228
|
+
|
229
|
+
case target
|
230
|
+
when ZergXcode::XcodeObject
|
231
|
+
cross_op = :cross_reference_objects
|
232
|
+
when Hash
|
233
|
+
cross_op = :cross_reference_hashes
|
234
|
+
when Enumerable
|
235
|
+
cross_op = :cross_reference_enumerables
|
236
|
+
else
|
237
|
+
return mappings
|
238
|
+
end
|
239
|
+
|
240
|
+
self.send cross_op, source, target, mappings
|
241
|
+
end
|
242
|
+
|
243
|
+
def cross_reference_objects(source, target, mappings)
|
244
|
+
return mappings if mappings[source] || mappings[target]
|
245
|
+
return mappings if source.xref_key != target.xref_key
|
246
|
+
|
247
|
+
mappings[target] = target
|
248
|
+
mappings[source] = target
|
249
|
+
cross_reference source._attr_hash, target._attr_hash, mappings
|
250
|
+
end
|
251
|
+
private :cross_reference_objects
|
252
|
+
|
253
|
+
def cross_reference_hashes(source, target, mappings)
|
254
|
+
source.each_key do |key|
|
255
|
+
p [source.keys, key] if source[key].nil?
|
256
|
+
cross_reference source[key], target[key], mappings if target[key]
|
257
|
+
end
|
258
|
+
mappings
|
259
|
+
end
|
260
|
+
private :cross_reference_hashes
|
261
|
+
|
262
|
+
def cross_reference_enumerables(source, target, mappings)
|
263
|
+
source_keys = {}
|
264
|
+
source.each do |value|
|
265
|
+
next unless value.kind_of? ZergXcode::XcodeObject
|
266
|
+
source_keys[value.xref_key] = value
|
267
|
+
end
|
268
|
+
target.each do |value|
|
269
|
+
next unless value.kind_of? ZergXcode::XcodeObject
|
270
|
+
next unless source_value = source_keys[value.xref_key]
|
271
|
+
cross_reference source_value, value, mappings
|
272
|
+
end
|
273
|
+
mappings
|
274
|
+
end
|
275
|
+
private :cross_reference_enumerables
|
276
|
+
end
|
277
|
+
|
278
|
+
class ZergXcode::XcodeObject
|
279
|
+
def xref_key
|
280
|
+
# If the object doesn't have a merge name, use its (unique) object_id.
|
281
|
+
[isa, xref_name || object_id]
|
282
|
+
end
|
283
|
+
|
284
|
+
def xref_name
|
285
|
+
# Do not use this to override xref_name for specific objects. Only use
|
286
|
+
# it for object families.
|
287
|
+
case isa.to_s
|
288
|
+
when /BuildPhase$/
|
289
|
+
isa.to_s
|
290
|
+
else
|
291
|
+
self['name'] || self['explicitPath'] || self['path']
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
class ZergXcode::Objects::PBXBuildFile
|
297
|
+
def xref_name
|
298
|
+
self['fileRef'].xref_name
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class ZergXcode::Objects::PBXProject
|
303
|
+
def xref_name
|
304
|
+
isa.to_s
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
class ZergXcode::Objects::XCConfigurationList
|
309
|
+
def xref_name
|
310
|
+
isa.to_s
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
class ZergXcode::Objects::PBXContainerItemProxy
|
315
|
+
def xref_name
|
316
|
+
self['remoteInfo']
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
class ZergXcode::Objects::PBXTargetDependency
|
321
|
+
def xref_name
|
322
|
+
target.xref_name
|
18
323
|
end
|
19
324
|
end
|
data/lib/zerg_xcode.rb
CHANGED
@@ -10,8 +10,12 @@ require 'zerg_xcode/file_format/paths.rb'
|
|
10
10
|
|
11
11
|
require 'zerg_xcode/objects/xcode_object.rb'
|
12
12
|
require 'zerg_xcode/objects/pbx_build_file.rb'
|
13
|
+
require 'zerg_xcode/objects/pbx_container_item_proxy.rb'
|
14
|
+
require 'zerg_xcode/objects/pbx_group.rb'
|
13
15
|
require 'zerg_xcode/objects/pbx_native_target.rb'
|
14
16
|
require 'zerg_xcode/objects/pbx_project.rb'
|
17
|
+
require 'zerg_xcode/objects/pbx_target_dependency.rb'
|
18
|
+
require 'zerg_xcode/objects/xc_configuration_list.rb'
|
15
19
|
require 'zerg_xcode/plugins/core/core.rb'
|
16
20
|
|
17
21
|
require 'zerg_xcode/shortcuts.rb'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'zerg_xcode'
|
4
|
+
|
5
|
+
class PBXContainerItemProxyTest < Test::Unit::TestCase
|
6
|
+
PBXContainerItemProxy = ZergXcode::Objects::PBXContainerItemProxy
|
7
|
+
|
8
|
+
def test_target
|
9
|
+
proj = ZergXcode.load 'testdata/ZergSupport.xcodeproj/project.pbxproj'
|
10
|
+
proxy = proj['targets'][2]['dependencies'].first['targetProxy']
|
11
|
+
assert_equal PBXContainerItemProxy, proxy.class
|
12
|
+
assert_equal proj['targets'][1], proxy.target
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'zerg_xcode'
|
4
|
+
|
5
|
+
class PBXGroupTest < Test::Unit::TestCase
|
6
|
+
PBXGroup = ZergXcode::Objects::PBXGroup
|
7
|
+
|
8
|
+
def test_instantiation
|
9
|
+
proj = ZergXcode.load 'testdata/project.pbxproj'
|
10
|
+
assert_equal PBXGroup, proj['mainGroup'].class
|
11
|
+
end
|
12
|
+
end
|
@@ -59,4 +59,16 @@ class PBXProjectTest < Test::Unit::TestCase
|
|
59
59
|
and_return(nil)
|
60
60
|
project.save!
|
61
61
|
end
|
62
|
+
|
63
|
+
def test_root_path
|
64
|
+
project = ZergXcode.load('testdata/ZergSupport.xcodeproj')
|
65
|
+
assert_equal 'testdata', project.root_path
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_copy_metadata
|
69
|
+
project = ZergXcode.load('testdata/ZergSupport.xcodeproj')
|
70
|
+
clone = ZergXcode::XcodeObject.from project
|
71
|
+
|
72
|
+
assert_equal project.source_filename, clone.source_filename
|
73
|
+
end
|
62
74
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'zerg_xcode'
|
4
|
+
|
5
|
+
class PBXTargetDependencyTest < Test::Unit::TestCase
|
6
|
+
PBXTargetDependency = ZergXcode::Objects::PBXTargetDependency
|
7
|
+
|
8
|
+
def test_target
|
9
|
+
proj = ZergXcode.load 'testdata/ZergSupport.xcodeproj/project.pbxproj'
|
10
|
+
dependency = proj['targets'][2]['dependencies'].first
|
11
|
+
assert_equal PBXTargetDependency, dependency.class
|
12
|
+
assert_equal proj['targets'][1], dependency.target
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'zerg_xcode'
|
4
|
+
|
5
|
+
class XCConfigurationListTest < Test::Unit::TestCase
|
6
|
+
XCConfigurationList = ZergXcode::Objects::XCConfigurationList
|
7
|
+
|
8
|
+
def test_instantiation
|
9
|
+
proj = ZergXcode.load 'testdata/project.pbxproj'
|
10
|
+
assert_equal XCConfigurationList, proj['buildConfigurationList'].class
|
11
|
+
end
|
12
|
+
end
|
@@ -46,6 +46,32 @@ class ObjectTest < Test::Unit::TestCase
|
|
46
46
|
assert_equal golden_visited.sort, visited.sort
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_visit_once
|
50
|
+
golden_visited = [
|
51
|
+
[49, 'sub1', @sub1],
|
52
|
+
[39, 'array', @sub1[:array]],
|
53
|
+
[39, '0', 'a'],
|
54
|
+
[39, '1', 'b'],
|
55
|
+
[39, '2', 'c'],
|
56
|
+
[39, 'string', 's'],
|
57
|
+
[39, 'root', @root],
|
58
|
+
[49, 'sub2', @sub2],
|
59
|
+
[42, 'hash', @sub2[:hash]],
|
60
|
+
[42, 'k', 'v'],
|
61
|
+
[42, 'k2', 'v2'],
|
62
|
+
[42, 'sub1', @sub1],
|
63
|
+
]
|
64
|
+
@sub1['root'] = @root
|
65
|
+
|
66
|
+
visited = []
|
67
|
+
@root.visit_once do |object, parent, key, value|
|
68
|
+
assert_equal value, parent[key], 'Parent/Key/Value check'
|
69
|
+
visited << [object.archive_id, key.to_s, value]
|
70
|
+
next true
|
71
|
+
end
|
72
|
+
assert_equal golden_visited.sort, visited.sort
|
73
|
+
end
|
74
|
+
|
49
75
|
def test_mutating_visit
|
50
76
|
golden_visited = [
|
51
77
|
[49, 'sub1', @sub1],
|