xcodeproject 0.1.1

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.
Files changed (53) hide show
  1. data/.gitignore +32 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +14 -0
  5. data/lib/xcodeproject/build_phase_node.rb +87 -0
  6. data/lib/xcodeproject/data.rb +87 -0
  7. data/lib/xcodeproject/exceptions.rb +5 -0
  8. data/lib/xcodeproject/extend/array.rb +8 -0
  9. data/lib/xcodeproject/extend/hash.rb +11 -0
  10. data/lib/xcodeproject/extend/string.rb +7 -0
  11. data/lib/xcodeproject/file_node.rb +63 -0
  12. data/lib/xcodeproject/formatter.rb +23 -0
  13. data/lib/xcodeproject/node.rb +15 -0
  14. data/lib/xcodeproject/pbx_build_file.rb +37 -0
  15. data/lib/xcodeproject/pbx_file_reference.rb +53 -0
  16. data/lib/xcodeproject/pbx_group.rb +169 -0
  17. data/lib/xcodeproject/pbx_native_target.rb +70 -0
  18. data/lib/xcodeproject/pbx_project.rb +33 -0
  19. data/lib/xcodeproject/project.rb +70 -0
  20. data/lib/xcodeproject/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.h +1 -0
  21. data/lib/xcodeproject/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.m +1 -0
  22. data/lib/xcodeproject/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.h +1 -0
  23. data/lib/xcodeproject/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.m +1 -0
  24. data/lib/xcodeproject/resources/example/dir1b/dir2b/file3b.m +0 -0
  25. data/lib/xcodeproject/resources/example/dir1b/file2b.m +0 -0
  26. data/lib/xcodeproject/resources/example/dir1c/file2c.h +0 -0
  27. data/lib/xcodeproject/resources/example/dir1c/file2c.m +0 -0
  28. data/lib/xcodeproject/resources/example/example/AppDelegate.h +15 -0
  29. data/lib/xcodeproject/resources/example/example/AppDelegate.m +57 -0
  30. data/lib/xcodeproject/resources/example/example/en.lproj/InfoPlist.strings +2 -0
  31. data/lib/xcodeproject/resources/example/example/example-Info.plist +45 -0
  32. data/lib/xcodeproject/resources/example/example/example-Prefix.pch +14 -0
  33. data/lib/xcodeproject/resources/example/example/main.m +18 -0
  34. data/lib/xcodeproject/resources/example/example.xcodeproj/project.pbxproj +324 -0
  35. data/lib/xcodeproject/root_node.rb +117 -0
  36. data/lib/xcodeproject/spec/build_phase_node_spec.rb +95 -0
  37. data/lib/xcodeproject/spec/file_node_spec.rb +83 -0
  38. data/lib/xcodeproject/spec/pbx_build_file_spec.rb +25 -0
  39. data/lib/xcodeproject/spec/pbx_file_reference_spec.rb +34 -0
  40. data/lib/xcodeproject/spec/pbx_group_spec.rb +274 -0
  41. data/lib/xcodeproject/spec/pbx_native_target_spec.rb +58 -0
  42. data/lib/xcodeproject/spec/pbx_project_spec.rb +34 -0
  43. data/lib/xcodeproject/spec/project_spec.rb +79 -0
  44. data/lib/xcodeproject/spec/spec_helper.rb +45 -0
  45. data/lib/xcodeproject/spec/xc_configuration_list_spec.rb +20 -0
  46. data/lib/xcodeproject/uuid_generator.rb +13 -0
  47. data/lib/xcodeproject/version.rb +3 -0
  48. data/lib/xcodeproject/xc_build_configuration.rb +15 -0
  49. data/lib/xcodeproject/xc_configuration_list.rb +23 -0
  50. data/lib/xcodeproject.rb +3 -0
  51. data/rakefile +3 -0
  52. data/xcodeproject.gemspec +26 -0
  53. metadata +166 -0
@@ -0,0 +1,117 @@
1
+ #--
2
+ # Copyright 2012 by Andrey Nesterov (ae.nesterov@gmail.com)
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to
6
+ # deal in the Software without restriction, including without limitation the
7
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8
+ # sell copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
+ # IN THE SOFTWARE.
21
+ #++
22
+
23
+ require 'xcodeproject/xc_build_configuration'
24
+ require 'xcodeproject/pbx_native_target'
25
+ require 'xcodeproject/pbx_project'
26
+ require 'xcodeproject/pbx_group'
27
+ require 'xcodeproject/build_phase_node'
28
+ require 'xcodeproject/uuid_generator'
29
+ require 'xcodeproject/exceptions'
30
+ require 'xcodeproject/extend/string'
31
+ require 'xcodeproject/extend/array'
32
+ require 'xcodeproject/extend/hash'
33
+
34
+ module XCodeProject
35
+ class RootNode
36
+ def initialize (data, wd)
37
+ @data, @wd = data, Pathname.new(wd)
38
+
39
+ @objects = data['objects']
40
+ @uuid_generator = UUIDGenerator.new
41
+ end
42
+
43
+ def project
44
+ find_object!('PBXProject')
45
+ end
46
+
47
+ def build_files (file_ref_uuid)
48
+ find_objects('PBXBuildFile', {'fileRef' => file_ref_uuid})
49
+ end
50
+
51
+ def object (uuid)
52
+ data = @objects[uuid]
53
+ XCodeProject.const_get(data['isa']).new(self, uuid, data) unless data.nil?
54
+ end
55
+
56
+ def object! (uuid)
57
+ obj = object(uuid)
58
+ raise ParseError.new("Object with uuid = #{uuid} not found.") if obj.nil?; obj
59
+ end
60
+
61
+ def select_objects
62
+ objs = @objects.select {|uuid, data| yield uuid, data }
63
+ objs.map {|uuid, data| object(uuid) }
64
+ end
65
+
66
+ def find_objects (isa, hash = Hash.new)
67
+ hash.merge!(Hash[ 'isa', isa ])
68
+ select_objects {|uuid, data| data.values_at(*hash.keys) == hash.values }
69
+ end
70
+
71
+ def find_objects! (isa, hash = Hash.new)
72
+ objs = find_objects(isa, hash)
73
+ raise ParseError.new("Object with isa = #{isa} and #{hash} not found.") if objs.empty?; objs
74
+ end
75
+
76
+ def find_object (isa, hash = Hash.new)
77
+ find_objects(isa, hash).first
78
+ end
79
+
80
+ def find_object! (isa, hash = Hash.new)
81
+ obj = find_object(isa, hash)
82
+ raise ParseError if obj.nil?; obj
83
+ end
84
+
85
+ def find_object2 (isa, h1 = Hash.new, h2 = Hash.new)
86
+ obj = find_object(isa, h1)
87
+ obj.nil? ? find_object(isa, h2) : obj
88
+ end
89
+
90
+ def find_object2! (isa, h1 = Hash.new, h2 = Hash.new)
91
+ obj = find_object2(isa, h1, h2)
92
+ raise ParseError if obj.nil?; obj
93
+ end
94
+
95
+ def add_object (data)
96
+ @objects.merge!(Hash[ uuid = generate_object_uuid, data ]); [uuid, data]
97
+ end
98
+
99
+ def remove_object (uuid)
100
+ @objects.delete(uuid)
101
+ end
102
+
103
+ def absolute_path (path)
104
+ path = Pathname.new(path)
105
+ path = path.absolute? ? path : @wd.join(path)
106
+ path.cleanpath
107
+ end
108
+
109
+ def generate_object_uuid
110
+ @uuid_generator.generate
111
+ end
112
+
113
+ def to_plist (fmtr = Formatter.new)
114
+ @data.to_plist
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::BuildPhaseNode do
4
+ let(:root) { prepare_example_project.read.send(:root) }
5
+ let(:file_ref) { root.project.main_group.file_ref('group1a/file2c.m') }
6
+ let(:build_file) { root.project.target('example').sources_build_phase.send(:build_file, file_ref.uuid) }
7
+ let(:obj) { obj = root.project.target('example').sources_build_phase }
8
+
9
+ describe "#files" do
10
+ it "returns an array of files" do
11
+ obj.files.should be_an_instance_of(Array)
12
+ obj.files.each {|obj| obj.should be_an_instance_of(XCodeProject::PBXFileReference) }
13
+ end
14
+ end
15
+
16
+ describe "#add_file" do
17
+ context "if passed an object of the PBXFileReference type" do
18
+ it "=> add_build_file" do
19
+ mock(obj).add_build_file(file_ref.uuid)
20
+ obj.add_file(file_ref)
21
+ end
22
+ end
23
+ context "if passed an object of the PBXBuildFile type" do
24
+ it "=> add_build_file_uuid" do
25
+ mock(obj).add_build_file_uuid(build_file.uuid)
26
+ obj.add_file(build_file)
27
+ end
28
+ end
29
+ context "if passed the object of unsupported type" do
30
+ it "raise an exception" do
31
+ lambda { obj.add_file(stub) }.should raise_exception(ArgumentError)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe "#remove_file" do
37
+ context "if passed an object of the PBXFileReference type" do
38
+ it "=> remove_build_file_uuid" do
39
+ mock(obj).remove_build_file_uuid(root.project.target('example').sources_build_phase.send(:build_file, file_ref.uuid).uuid)
40
+ obj.remove_file(file_ref)
41
+ end
42
+ end
43
+ context "if passed an object of the PBXBuildFile type" do
44
+ it "=> remove_build_file_uuid" do
45
+ mock(obj).remove_build_file_uuid(build_file.uuid)
46
+ obj.remove_file(build_file)
47
+ end
48
+ end
49
+ context "if passed the object of unsupported type" do
50
+ it "raise an exception" do
51
+ lambda { obj.remove_file(stub) }.should raise_exception(ArgumentError)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#build_files" do
57
+ it "returns an array of files" do
58
+ obj.send(:build_files).should be_an_instance_of(Array)
59
+ obj.send(:build_files).each {|obj| obj.should be_an_instance_of(XCodeProject::PBXBuildFile) }
60
+ end
61
+ end
62
+
63
+ describe "#build_file" do
64
+ it "returns the object" do
65
+ obj.send(:build_file, file_ref.uuid).should be_an_instance_of(XCodeProject::PBXBuildFile)
66
+ end
67
+ end
68
+
69
+ describe "#add_build_file" do
70
+ it "adds the build file, returns the object" do
71
+ obj.send(:add_build_file, file_ref.uuid).should be_an_instance_of(XCodeProject::PBXBuildFile)
72
+ end
73
+ end
74
+
75
+ describe "#remove_build_file" do
76
+ it "=> remove_build_file_uuid" do
77
+ mock(obj).remove_build_file_uuid(build_file.uuid)
78
+ obj.send(:remove_build_file, file_ref.uuid)
79
+ end
80
+ end
81
+
82
+ describe "#add_build_file_uuid" do
83
+ it "adds the build file uuid to the build list" do
84
+ obj.send(:add_build_file_uuid, build_file.uuid)
85
+ obj.send(:build_files).map {|obj| obj.uuid }.should include(build_file.uuid)
86
+ end
87
+ end
88
+
89
+ describe "#remove_build_file_uuid" do
90
+ it "removes the build file uuid from the build list" do
91
+ obj.send(:remove_build_file_uuid, build_file.uuid)
92
+ obj.send(:build_files).map {|obj| obj.uuid }.should_not include(build_file.uuid)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,83 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::FileNode do
4
+ let(:data_name) { Hash['name', 'file.name'] }
5
+ let(:data_path) { Hash['path', 'path/to/file.name'] }
6
+ let(:data_path_name) { data_path.merge!(data_name) }
7
+ let(:data_empty) { Hash.new }
8
+
9
+ describe "#name" do
10
+ context "if the name is initialized " do
11
+ it "returns the name as is" do
12
+ [data_name, data_path_name].each do |data|
13
+ XCodeProject::FileNode.new(stub, stub, data).name.should eql(data['name'])
14
+ end
15
+ end
16
+ end
17
+ context "if the name isn't initialized" do
18
+ context "and the path is initialized " do
19
+ it "returns the name as basename of the path" do
20
+ XCodeProject::FileNode.new(stub, stub, data_path).name.should eql(File.basename(data_path['path']))
21
+ end
22
+ end
23
+ context "and the path isn't initialized" do
24
+ it "returns nil" do
25
+ XCodeProject::FileNode.new(stub, stub, data_empty).name.should be_nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#path" do
32
+ context "if the path is initialized " do
33
+ it "returns the path as is" do
34
+ [data_path, data_path_name].each do |data|
35
+ XCodeProject::FileNode.new(stub, stub, data_path).path.should eql(data['path'])
36
+ end
37
+ end
38
+ end
39
+ context "if the path isn't initialized" do
40
+ it "returns nil" do
41
+ XCodeProject::FileNode.new(stub, stub, data_empty).path.should be_nil
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#parent" do
47
+ let(:root) { prepare_example_project.read.send(:root) }
48
+
49
+ context "if the current object is the main group" do
50
+ it "returns nil" do
51
+ root.project.main_group.parent.should be_nil
52
+ end
53
+ end
54
+ end
55
+
56
+ shared_examples_for "a file node" do
57
+ describe "#parent" do
58
+ context "if the object is nested file node" do
59
+ it "returns the parent object" do
60
+ file_nodes_gpaths do |gpath|
61
+ main_group.child(gpath).parent.should be_an_instance_of(XCodeProject::PBXGroup)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#group_path" do
68
+ it "returns the abstract path from project main group" do
69
+ file_nodes_gpaths.map do |gpath|
70
+ main_group.child(gpath).group_path
71
+ end.should eql(file_nodes_gpaths.map {|gpath| Pathname.new(gpath) })
72
+ end
73
+ end
74
+
75
+ describe "#total_path" do
76
+ it "returns the absolute file path" do
77
+ file_nodes_gpaths.map do |gpath|
78
+ main_group.child(gpath).total_path
79
+ end.should eql(file_nodes_total_paths.map {|gpath| Pathname.new(gpath) })
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::PBXBuildFile do
4
+ let(:root) { prepare_example_project.read.send(:root) }
5
+ let(:obj_file_ref) { root.project.main_group.file_ref("group1a/file2c.m") }
6
+ let(:obj) { root.project.target('example').sources_build_phase.send(:build_file, obj_file_ref.uuid) }
7
+
8
+ describe "#file_ref" do
9
+ it "returns the object" do
10
+ obj.file_ref.should be_an_instance_of(XCodeProject::PBXFileReference)
11
+ end
12
+ end
13
+
14
+ describe "#remove!" do
15
+ it "removes the current build file" do
16
+ obj.remove!
17
+ root.project.target('example').sources_build_phase.send(:build_file, obj_file_ref.uuid).should be_nil
18
+ end
19
+ it "removes the current build file from all targets" do
20
+ root.project.targets.each do |target|
21
+ target.sources.map {|obj| obj.uuid }.should_not include(obj.uuid)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::PBXFileReference do
4
+ let(:root) { prepare_example_project.read.send(:root) }
5
+ let(:obj_gpath) { "group1a/file2c.m" }
6
+ let(:obj) { root.project.main_group.file_ref(obj_gpath) }
7
+
8
+ describe "#remove!" do
9
+ it "removes the current file reference" do
10
+ obj.remove!
11
+ root.project.main_group.file_ref(obj_gpath).should be_nil
12
+ end
13
+ it "removes build files which has been bonded with the current file reference" do
14
+ obj.remove!
15
+ root.build_files(obj.uuid).should be_empty
16
+ end
17
+ end
18
+
19
+ it_behaves_like "a file node" do
20
+ let(:main_group) {
21
+ root.project.main_group
22
+ }
23
+ let(:file_nodes_gpaths) {[
24
+ "group1a/dir2c/dir3a/dir4a/file5a-a.m",
25
+ "group1a/dir2c/dir3a/dir4a/file5a-r.m",
26
+ "group1a/file2c.m"
27
+ ]}
28
+ let(:file_nodes_total_paths) {[
29
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m",
30
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-r.m",
31
+ "#{example_project_dir}/dir1c/file2c.m"
32
+ ]}
33
+ end
34
+ end
@@ -0,0 +1,274 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::PBXGroup do
4
+ let(:root) { prepare_example_project.read.send(:root) }
5
+ let(:obj) { root.project.main_group.group('group1a') }
6
+
7
+ describe "#children" do
8
+ context "if children exists" do
9
+ it "returns an array of children objects" do
10
+ obj.children.should be_an_instance_of(Array)
11
+ obj.children.size.should > 0
12
+ end
13
+ end
14
+ context "if children doesn't exist" do
15
+ let(:empty_group_obj) { root.project.main_group.group("group1a/group2a") }
16
+
17
+ it "returns an empty array" do
18
+ empty_group_obj.children.should be_an_instance_of(Array)
19
+ empty_group_obj.children.size.should eql(0)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#child" do
25
+ context "if passed '.'" do
26
+ it "returns the self" do
27
+ obj.child('.').uuid.should eql(obj.uuid)
28
+ end
29
+ end
30
+ context "if passed '..'" do
31
+ it "returns the parent" do
32
+ obj.child('..').uuid.should eql(obj.parent.uuid)
33
+ end
34
+ end
35
+ context "if passed a child name" do
36
+ it "returns the child object" do
37
+ [
38
+ 'group2a',
39
+ 'dir2c',
40
+ 'file2c.m'
41
+ ].each do |name|
42
+ obj.child(name).should_not be_nil
43
+ end
44
+ end
45
+ end
46
+ context "if passed the group path" do
47
+ it "returns the child object" do
48
+ [
49
+ 'dir2c/dir3a',
50
+ 'dir2c/dir3a/dir4a/file5a-a.m',
51
+ 'dir2c/dir3a/dir4a/file5a-r.m',
52
+ 'dir2c/../dir2c/dir3a/./dir4a/file5a-r.m'
53
+ ].each do |gpath|
54
+ obj.child(gpath).should_not be_nil
55
+ end
56
+ end
57
+ end
58
+ context "if child doesn't exist" do
59
+ it "returns nil" do
60
+ [
61
+ 'group2a_ghost',
62
+ 'group2a_ghost/file3c_ghost.m',
63
+ 'dir2c/file3c_ghost.m'
64
+ ].each do |gpath|
65
+ obj.child(gpath).should be_nil
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ describe "#group?" do
72
+ let(:dir_obj) { obj.child('dir2c') }
73
+
74
+ context "if the current group is abstract" do
75
+ it "returns true" do
76
+ obj.group?.should eql(true)
77
+ end
78
+ end
79
+ context "if the current group is directory" do
80
+ it "returns false" do
81
+ dir_obj.group?.should eql(false)
82
+ end
83
+ end
84
+ end
85
+
86
+ describe "#dir?" do
87
+ let(:dir_obj) { obj.child('dir2c') }
88
+
89
+ context "if the current group is directory" do
90
+ it "returns true" do
91
+ dir_obj.dir?.should eql(true)
92
+ end
93
+ end
94
+ context "if the current group is abstract" do
95
+ it "returns false" do
96
+ obj.dir?.should eql(false)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "#group" do
102
+ context "if the group exists" do
103
+ it "returns the object" do
104
+ obj.group('group2a').should be_an_instance_of(XCodeProject::PBXGroup)
105
+ end
106
+ end
107
+ context "if the group doesn't exist" do
108
+ it "returns nil" do
109
+ obj.group('group2a_ghost').should be_nil
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "#file_ref" do
115
+ context "if the file reference exists" do
116
+ it "returns the object" do
117
+ obj.file_ref('file2c.m').should be_an_instance_of(XCodeProject::PBXFileReference)
118
+ end
119
+ end
120
+ context "if the file reference doesn't exist" do
121
+ it "returns nil" do
122
+ obj.file_ref('file2c_ghost.m').should be_nil
123
+ end
124
+ end
125
+ end
126
+
127
+ describe "#add_file_ref" do
128
+ context "if passed the relative path" do
129
+ it "adds the file reference, returns the object" do
130
+ obj.send(:add_file_ref, 'dir1b/file2b.m').should be_an_instance_of(XCodeProject::PBXFileReference)
131
+ end
132
+ end
133
+ context "if passed the absolute path" do
134
+ it "adds the file reference, returns the object" do
135
+ obj.send(:add_file_ref, "#{example_project_dir}/dir1b/file2b.m").should be_an_instance_of(XCodeProject::PBXFileReference)
136
+ end
137
+ end
138
+ context "if file reference already exists" do
139
+ it "new object has same uuid as existing" do
140
+ uuid = obj.file_ref('file2c.m').uuid
141
+ obj.send(:add_file_ref, 'dir1c/file2c.m').uuid.should eql(uuid)
142
+ end
143
+ end
144
+ context "if file doesn't exit" do
145
+ it "raise an exception " do
146
+ lambda { obj.send(:add_file_ref, "file2c_ghost.m") }.should raise_exception(XCodeProject::FilePathError)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe "#add_group" do
152
+ it "adds the group, returns the object" do
153
+ group_obj = obj.add_group("group2a_ghost")
154
+ group_obj.should be_an_instance_of(XCodeProject::PBXGroup)
155
+ group_obj.group?.should eql(true)
156
+ end
157
+ end
158
+
159
+ describe "#add_dir" do
160
+ it "adds the group, returns the object" do
161
+ group_obj = obj.add_dir("dir1c")
162
+ group_obj.should be_an_instance_of(XCodeProject::PBXGroup)
163
+ group_obj.dir?.should eql(true)
164
+ end
165
+ it "adds all dir's children" do
166
+ obj.add_dir('dir1c')
167
+ [
168
+ obj.group('dir1c'),
169
+ obj.group('dir1c/dir2c'),
170
+ obj.file('dir1c/file2c.m')
171
+ ].each {|obj| obj.should_not be_nil }
172
+ end
173
+ context "if dir doesn't exit" do
174
+ it "raise an exception " do
175
+ lambda { obj.add_dir("dir2c_ghost") }.should raise_exception(XCodeProject::FilePathError)
176
+ end
177
+ end
178
+ end
179
+
180
+ describe "#create_group" do
181
+ context "if passed a group name" do
182
+ it "creates and returns the group object" do
183
+ obj.create_group('group2a_ghost').should be_an_instance_of(XCodeProject::PBXGroup)
184
+ end
185
+ end
186
+ context "if passed a group path" do
187
+ it "creates missed groups and returns the last group object" do
188
+ [
189
+ 'group2a/group3a_ghost',
190
+ 'group2a_ghost/group3a_ghost',
191
+ 'group2a_ghost/../create_group2a_ghost/./group3a_ghost'
192
+ ].each do |gpath|
193
+ obj.create_group(gpath).should be_an_instance_of(XCodeProject::PBXGroup)
194
+ end
195
+ end
196
+ end
197
+ context "if group already exists" do
198
+ it "new object has same uuid as existing" do
199
+ uuid = obj.child('group2a').uuid
200
+ obj.create_group('group2a').uuid.should eql(uuid)
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "#remove_group" do
206
+ context "if the group exists" do
207
+ it "removes the object" do
208
+ obj.remove_group('group2a')
209
+ obj.group('group2a').should be_nil
210
+ end
211
+ end
212
+ context "if the group doesn't exist" do
213
+ it "returns nil" do
214
+ obj.remove_group('group2a_ghost').should be_nil
215
+ end
216
+ end
217
+ end
218
+
219
+ describe "#remove!" do
220
+ it "removes the current group" do
221
+ obj.remove!
222
+ root.project.main_group.group('group1a').should be_nil
223
+ end
224
+ end
225
+
226
+ describe "#absolute_path" do
227
+ let(:dir_obj) { root.project.main_group.group('group1a/dir2c/dir3a') }
228
+
229
+ it "makes the absolute path" do
230
+ [
231
+ "dir4a/file5a-a.m",
232
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"
233
+ ].map {|path| dir_obj.absolute_path(path) }.should eql([
234
+ Pathname.new("#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"),
235
+ Pathname.new("#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m")
236
+ ])
237
+ end
238
+ end
239
+
240
+ describe "#relative_path" do
241
+ let(:dir_obj) { root.project.main_group.group('group1a/dir2c/dir3a') }
242
+
243
+ it "makes the relative path" do
244
+ [
245
+ "dir4a/file5a-a.m",
246
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"
247
+ ].map {|path| dir_obj.relative_path(path) }.should eql([
248
+ Pathname.new("dir4a/file5a-a.m"),
249
+ Pathname.new("dir4a/file5a-a.m")
250
+ ])
251
+ end
252
+ end
253
+
254
+ it_behaves_like "a file node" do
255
+ let(:main_group) {
256
+ root.project.main_group
257
+ }
258
+ let(:file_nodes_gpaths) {[
259
+ "group1a/dir2c/dir3a/dir4a",
260
+ "group1a/dir2c/dir3a",
261
+ "group1a/dir2c",
262
+ "group1a/group2a",
263
+ "group1a"
264
+ ]}
265
+ let(:file_nodes_total_paths) {[
266
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a",
267
+ "#{example_project_dir}/dir1a/dir2a/dir3a",
268
+ "#{example_project_dir}/dir1c/dir2c",
269
+ example_project_dir,
270
+ example_project_dir
271
+ ]}
272
+ end
273
+ end
274
+
@@ -0,0 +1,58 @@
1
+ require "spec_helper"
2
+
3
+ describe XCodeProject::PBXNativeTarget do
4
+ before(:each) { @data = prepare_example_project.read }
5
+ let(:obj) { obj = @data.target('example') }
6
+
7
+ describe "#sources" do
8
+ it "=> PBXSourcesBuildPhase#files" do
9
+ files = mock
10
+ mock(obj).sources_build_phase.mock!.files { files }
11
+ obj.sources.should eql(files)
12
+ end
13
+ end
14
+
15
+ describe "#add_source" do
16
+ it "=> PBXSourcesBuildPhase#add_file" do
17
+ file = mock
18
+ mock(obj).sources_build_phase.mock!.add_file(file)
19
+ obj.add_source(file)
20
+ end
21
+ end
22
+
23
+ describe "#remove_source" do
24
+ it "=> PBXSourcesBuildPhase#remove_file" do
25
+ file = mock
26
+ mock(obj).sources_build_phase.mock!.remove_file(file)
27
+ obj.remove_source(file)
28
+ end
29
+ end
30
+
31
+ describe "#build_configurations_list" do
32
+ it "returns the build configuration list object" do
33
+ obj.build_configurations_list.should be_an_instance_of(XCodeProject::XCConfigurationList)
34
+ end
35
+ end
36
+
37
+ describe "#configs" do
38
+ it "=> XCConfigurationList#build_configurations" do
39
+ res = mock
40
+ mock(obj).build_configurations_list.mock!.build_configurations { res }
41
+ obj.configs.should eql(res)
42
+ end
43
+ end
44
+
45
+ describe "#config" do
46
+ it "=> XCConfigurationList#build_configuration" do
47
+ name, res = mock, mock
48
+ mock(obj).build_configurations_list.mock!.build_configuration(name) { res }
49
+ obj.config(name).should eql(res)
50
+ end
51
+ end
52
+
53
+ describe "#build_phases" do
54
+ it "returns the array of build phase objects" do
55
+ obj.build_phases.should be_an_instance_of(Array)
56
+ end
57
+ end
58
+ end