xcodeproject_swift 0.3.13

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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +37 -0
  5. data/.travis.yml +13 -0
  6. data/.yardopts +7 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +22 -0
  9. data/README.md +192 -0
  10. data/Rakefile +11 -0
  11. data/lib/xcodeproject.rb +2 -0
  12. data/lib/xcodeproject/build_phase_node.rb +111 -0
  13. data/lib/xcodeproject/data.rb +89 -0
  14. data/lib/xcodeproject/exceptions.rb +29 -0
  15. data/lib/xcodeproject/extend/array.rb +32 -0
  16. data/lib/xcodeproject/extend/hash.rb +35 -0
  17. data/lib/xcodeproject/extend/string.rb +31 -0
  18. data/lib/xcodeproject/file_node.rb +86 -0
  19. data/lib/xcodeproject/formatter.rb +47 -0
  20. data/lib/xcodeproject/node.rb +42 -0
  21. data/lib/xcodeproject/pbx_build_file.rb +63 -0
  22. data/lib/xcodeproject/pbx_file_reference.rb +82 -0
  23. data/lib/xcodeproject/pbx_group.rb +204 -0
  24. data/lib/xcodeproject/pbx_native_target.rb +94 -0
  25. data/lib/xcodeproject/pbx_project.rb +57 -0
  26. data/lib/xcodeproject/project.rb +72 -0
  27. data/lib/xcodeproject/root_node.rb +127 -0
  28. data/lib/xcodeproject/tasks/build_task.rb +59 -0
  29. data/lib/xcodeproject/uuid_generator.rb +37 -0
  30. data/lib/xcodeproject/version.rb +27 -0
  31. data/lib/xcodeproject/xc_build_configuration.rb +98 -0
  32. data/lib/xcodeproject/xc_configuration_list.rb +47 -0
  33. data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.h +1 -0
  34. data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-a.m +1 -0
  35. data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.h +1 -0
  36. data/resources/example/dir1a/dir2a/dir3a/dir4a/file5a-r.m +1 -0
  37. data/resources/example/dir1b/dir2b/file3b.m +0 -0
  38. data/resources/example/dir1b/file2b.m +0 -0
  39. data/resources/example/dir1c/file2c.h +0 -0
  40. data/resources/example/dir1c/file2c.m +0 -0
  41. data/resources/example/example.xcodeproj/project.pbxproj +324 -0
  42. data/resources/example/example/AppDelegate.h +7 -0
  43. data/resources/example/example/AppDelegate.m +49 -0
  44. data/resources/example/example/en.lproj/InfoPlist.strings +2 -0
  45. data/resources/example/example/example-Info.plist +45 -0
  46. data/resources/example/example/example-Prefix.pch +14 -0
  47. data/resources/example/example/main.m +10 -0
  48. data/spec/build_phase_node_spec.rb +103 -0
  49. data/spec/file_node_spec.rb +58 -0
  50. data/spec/pbx_build_file_spec.rb +26 -0
  51. data/spec/pbx_file_reference_spec.rb +42 -0
  52. data/spec/pbx_group_spec.rb +360 -0
  53. data/spec/pbx_native_target_spec.rb +62 -0
  54. data/spec/pbx_project_spec.rb +39 -0
  55. data/spec/project_spec.rb +86 -0
  56. data/spec/spec_helper.rb +67 -0
  57. data/spec/support/shared_examples/file_node_shared_examples.rb +27 -0
  58. data/spec/xc_build_configuration_spec.rb +114 -0
  59. data/spec/xc_configuration_list_spec.rb +23 -0
  60. data/xcodeproject.gemspec +29 -0
  61. metadata +233 -0
@@ -0,0 +1,7 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ @interface AppDelegate : UIResponder <UIApplicationDelegate>
4
+
5
+ @property (strong, nonatomic) UIWindow *window;
6
+
7
+ @end
@@ -0,0 +1,49 @@
1
+ #import "AppDelegate.h"
2
+
3
+ @implementation AppDelegate
4
+
5
+ @synthesize window = _window;
6
+
7
+ - (void)dealloc
8
+ {
9
+ [_window release];
10
+ [super dealloc];
11
+ }
12
+
13
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14
+ {
15
+ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
16
+ // Override point for customization after application launch.
17
+ self.window.backgroundColor = [UIColor whiteColor];
18
+ [self.window makeKeyAndVisible];
19
+ return YES;
20
+ }
21
+
22
+ - (void)applicationWillResignActive:(UIApplication *)application
23
+ {
24
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26
+ }
27
+
28
+ - (void)applicationDidEnterBackground:(UIApplication *)application
29
+ {
30
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
31
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
32
+ }
33
+
34
+ - (void)applicationWillEnterForeground:(UIApplication *)application
35
+ {
36
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
37
+ }
38
+
39
+ - (void)applicationDidBecomeActive:(UIApplication *)application
40
+ {
41
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
42
+ }
43
+
44
+ - (void)applicationWillTerminate:(UIApplication *)application
45
+ {
46
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
47
+ }
48
+
49
+ @end
@@ -0,0 +1,2 @@
1
+ /* Localized versions of Info.plist keys */
2
+
@@ -0,0 +1,45 @@
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>CFBundleDisplayName</key>
8
+ <string>${PRODUCT_NAME}</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>${EXECUTABLE_NAME}</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>org.yanot.${PRODUCT_NAME:rfc1034identifier}</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>${PRODUCT_NAME}</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>APPL</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>1.0</string>
21
+ <key>CFBundleSignature</key>
22
+ <string>????</string>
23
+ <key>CFBundleVersion</key>
24
+ <string>345</string>
25
+ <key>LSRequiresIPhoneOS</key>
26
+ <true/>
27
+ <key>UIRequiredDeviceCapabilities</key>
28
+ <array>
29
+ <string>armv7</string>
30
+ </array>
31
+ <key>UISupportedInterfaceOrientations</key>
32
+ <array>
33
+ <string>UIInterfaceOrientationPortrait</string>
34
+ <string>UIInterfaceOrientationLandscapeLeft</string>
35
+ <string>UIInterfaceOrientationLandscapeRight</string>
36
+ </array>
37
+ <key>UISupportedInterfaceOrientations~ipad</key>
38
+ <array>
39
+ <string>UIInterfaceOrientationPortrait</string>
40
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
41
+ <string>UIInterfaceOrientationLandscapeLeft</string>
42
+ <string>UIInterfaceOrientationLandscapeRight</string>
43
+ </array>
44
+ </dict>
45
+ </plist>
@@ -0,0 +1,14 @@
1
+ //
2
+ // Prefix header for all source files of the 'example' target in the 'example' project
3
+ //
4
+
5
+ #import <Availability.h>
6
+
7
+ #ifndef __IPHONE_3_0
8
+ #warning "This project uses features only available in iOS SDK 3.0 and later."
9
+ #endif
10
+
11
+ #ifdef __OBJC__
12
+ #import <UIKit/UIKit.h>
13
+ #import <Foundation/Foundation.h>
14
+ #endif
@@ -0,0 +1,10 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ #import "AppDelegate.h"
4
+
5
+ int main(int argc, char *argv[])
6
+ {
7
+ @autoreleasepool {
8
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
9
+ }
10
+ }
@@ -0,0 +1,103 @@
1
+ require_relative '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) { root.project.target('example').sources_build_phase }
8
+
9
+ describe '#files' do
10
+ it 'returns an array of files' do
11
+ expect(obj.files).to be_a(Array)
12
+ obj.files.each do |obj|
13
+ expect(obj).to be_a(XcodeProject::PBXFileReference)
14
+ end
15
+ end
16
+ end
17
+
18
+ describe '#add_file' do
19
+ context 'if passed an object of the PBXFileReference type' do
20
+ it '=> add_build_file' do
21
+ mock(obj).add_build_file(file_ref.uuid)
22
+ obj.add_file(file_ref)
23
+ end
24
+ end
25
+
26
+ context 'if passed an object of the PBXBuildFile type' do
27
+ it '=> add_build_file_uuid' do
28
+ mock(obj).add_build_file_uuid(build_file.uuid)
29
+ obj.add_file(build_file)
30
+ end
31
+ end
32
+
33
+ context 'if passed the object of unsupported type' do
34
+ it 'raises an exception' do
35
+ expect { obj.add_file(stub) }.to raise_exception(ArgumentError)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#remove_file' do
41
+ context 'if passed an object of the PBXFileReference type' do
42
+ it '=> remove_build_file_uuid' do
43
+ mock(obj).remove_build_file_uuid(root.project.target('example').sources_build_phase.send(:build_file, file_ref.uuid).uuid)
44
+ obj.remove_file(file_ref)
45
+ end
46
+ end
47
+
48
+ context 'if passed an object of the PBXBuildFile type' do
49
+ it '=> remove_build_file_uuid' do
50
+ mock(obj).remove_build_file_uuid(build_file.uuid)
51
+ obj.remove_file(build_file)
52
+ end
53
+ end
54
+
55
+ context 'if passed the object of unsupported type' do
56
+ it 'raises an exception' do
57
+ expect { obj.remove_file(stub) }.to raise_exception(ArgumentError)
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#build_files' do
63
+ it 'returns an array of files' do
64
+ expect(obj.send(:build_files)).to be_a(Array)
65
+ obj.send(:build_files).each do |obj|
66
+ expect(obj).to be_a(XcodeProject::PBXBuildFile)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#build_file' do
72
+ it 'returns the object' do
73
+ expect(obj.send(:build_file, file_ref.uuid)).to be_a(XcodeProject::PBXBuildFile)
74
+ end
75
+ end
76
+
77
+ describe '#add_build_file' do
78
+ it 'adds the build file, returns the object' do
79
+ expect(obj.send(:add_build_file, file_ref.uuid)).to be_a(XcodeProject::PBXBuildFile)
80
+ end
81
+ end
82
+
83
+ describe '#remove_build_file' do
84
+ it '=> remove_build_file_uuid' do
85
+ mock(obj).remove_build_file_uuid(build_file.uuid)
86
+ obj.send(:remove_build_file, file_ref.uuid)
87
+ end
88
+ end
89
+
90
+ describe '#add_build_file_uuid' do
91
+ it 'adds the build file uuid to the build list' do
92
+ obj.send(:add_build_file_uuid, build_file.uuid)
93
+ expect(obj.send(:build_files).map(&:uuid)).to include(build_file.uuid)
94
+ end
95
+ end
96
+
97
+ describe '#remove_build_file_uuid' do
98
+ it 'removes the build file uuid from the build list' do
99
+ obj.send(:remove_build_file_uuid, build_file.uuid)
100
+ expect(obj.send(:build_files).map(&:uuid)).not_to include(build_file.uuid)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,58 @@
1
+ require_relative '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
+ expect(XcodeProject::FileNode.new(stub, stub, data).name).to eql(data['name'])
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'if the name isn\'t initialized' do
19
+ context 'and the path is initialized ' do
20
+ it 'returns the name as basename of the path' do
21
+ expect(XcodeProject::FileNode.new(stub, stub, data_path).name).to eql(File.basename(data_path['path']))
22
+ end
23
+ end
24
+
25
+ context 'and the path isn\'t initialized' do
26
+ it 'returns nil' do
27
+ expect(XcodeProject::FileNode.new(stub, stub, data_empty).name).to be_nil
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#path' do
34
+ context 'if the path is initialized' do
35
+ it 'returns the path as is' do
36
+ [data_path, data_path_name].each do |data|
37
+ expect(XcodeProject::FileNode.new(stub, stub, data_path).path).to eql(data['path'])
38
+ end
39
+ end
40
+ end
41
+
42
+ context 'if the path isn\'t initialized' do
43
+ it 'returns nil' do
44
+ expect(XcodeProject::FileNode.new(stub, stub, data_empty).path).to be_nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#parent' do
50
+ let(:root) { prepare_example_project.read.send(:root) }
51
+
52
+ context 'if the current object is the main group' do
53
+ it 'returns nil' do
54
+ expect(root.project.main_group.parent).to be_nil
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '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
+ expect(obj.file_ref).to be_a(XcodeProject::PBXFileReference)
11
+ end
12
+ end
13
+
14
+ describe '#remove!' do
15
+ it 'removes the current build file' do
16
+ obj.remove!
17
+ expect(root.project.target('example').sources_build_phase.send(:build_file, obj_file_ref.uuid)).to be_nil
18
+ end
19
+
20
+ it 'removes the current build file from all targets' do
21
+ root.project.targets.each do |target|
22
+ expect(target.sources.map(&:uuid)).not_to include(obj.uuid)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'spec_helper'
2
+ require 'file_node_spec'
3
+
4
+ describe XcodeProject::PBXFileReference do
5
+ let(:root) { prepare_example_project.read.send(:root) }
6
+ let(:obj_gpath) { 'group1a/file2c.m' }
7
+ let(:obj) { root.project.main_group.file_ref(obj_gpath) }
8
+
9
+ describe '#remove!' do
10
+ it 'removes the current file reference' do
11
+ obj.remove!
12
+ expect(root.project.main_group.file_ref(obj_gpath)).to be_nil
13
+ end
14
+
15
+ it 'removes build files which has been bonded with the current file reference' do
16
+ obj.remove!
17
+ expect(root.build_files(obj.uuid)).to be_empty
18
+ end
19
+ end
20
+
21
+ it_behaves_like 'a file node' do
22
+ let(:main_group) do
23
+ root.project.main_group
24
+ end
25
+
26
+ let(:file_nodes_gpaths) do
27
+ [
28
+ 'group1a/dir2c/dir3a/dir4a/file5a-a.m',
29
+ 'group1a/dir2c/dir3a/dir4a/file5a-r.m',
30
+ 'group1a/file2c.m'
31
+ ]
32
+ end
33
+
34
+ let(:file_nodes_total_paths) do
35
+ [
36
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m",
37
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-r.m",
38
+ "#{example_project_dir}/dir1c/file2c.m"
39
+ ]
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,360 @@
1
+ require_relative 'spec_helper'
2
+ require_relative 'file_node_spec'
3
+
4
+ describe XcodeProject::PBXGroup do
5
+ let(:root) { prepare_example_project.read.send(:root) }
6
+ let(:obj) { root.project.main_group.group('group1a') }
7
+
8
+ describe '#children' do
9
+ context 'if children exists' do
10
+ it 'returns an array of children objects' do
11
+ expect(obj.children).to be_a(Array)
12
+ expect(obj.children.size).to be > 0
13
+ end
14
+ end
15
+
16
+ context 'if children doesn\'t exist' do
17
+ let(:empty_group_obj) { root.project.main_group.group('group1a/group2a') }
18
+
19
+ it 'returns an empty array' do
20
+ expect(empty_group_obj.children).to be_a(Array)
21
+ expect(empty_group_obj.children.size).to eql(0)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#files' do
27
+ context 'if children exists' do
28
+ it 'Returns an array of only those children who are files' do
29
+ chs = obj.files
30
+ expect(chs).to be_a(Array)
31
+ expect(chs.size).to be > 0
32
+ chs.each do |child|
33
+ expect(child).to be_a(XcodeProject::PBXFileReference)
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'if children doesn\'t exist' do
39
+ let(:obj) { root.project.main_group.group('group1a/dir2c') }
40
+
41
+ it 'returns an empty array' do
42
+ chs = obj.files
43
+ expect(chs).to be_a(Array)
44
+ expect(chs.size).to eql(0)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#groups' do
50
+ context 'if children exists' do
51
+ it 'Returns an array of only those children who are group' do
52
+ chs = obj.groups
53
+ expect(chs).to be_a(Array)
54
+ expect(chs.size).to be > 0
55
+ chs.each do |child|
56
+ expect(child).to be_a(XcodeProject::PBXGroup)
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'if children doesn\'t exist' do
62
+ let(:obj) { root.project.main_group.group('group1a/dir2c/dir3a/dir4a') }
63
+
64
+ it 'returns an empty array' do
65
+ chs = obj.groups
66
+ expect(chs).to be_a(Array)
67
+ expect(chs.size).to eql(0)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#child' do
73
+ context "if passed '.'" do
74
+ it 'returns the self' do
75
+ expect(obj.child('.').uuid).to eql(obj.uuid)
76
+ end
77
+ end
78
+
79
+ context "if passed '..'" do
80
+ it 'returns the parent' do
81
+ expect(obj.child('..').uuid).to eql(obj.parent.uuid)
82
+ end
83
+ end
84
+
85
+ context 'if passed a child name' do
86
+ it 'returns the child object' do
87
+ [
88
+ 'group2a',
89
+ 'dir2c',
90
+ 'file2c.m'
91
+ ].each do |name|
92
+ expect(obj.child(name)).not_to be_nil
93
+ end
94
+ end
95
+ end
96
+
97
+ context 'if passed the group path' do
98
+ it 'returns the child object' do
99
+ [
100
+ 'dir2c/dir3a',
101
+ 'dir2c/dir3a/dir4a/file5a-a.m',
102
+ 'dir2c/dir3a/dir4a/file5a-r.m',
103
+ 'dir2c/../dir2c/dir3a/./dir4a/file5a-r.m'
104
+ ].each do |gpath|
105
+ expect(obj.child(gpath)).not_to be_nil
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'if child doesn\'t exist' do
111
+ it 'returns nil' do
112
+ [
113
+ 'group2a_ghost',
114
+ 'group2a_ghost/file3c_ghost.m',
115
+ 'dir2c/file3c_ghost.m'
116
+ ].each do |gpath|
117
+ expect(obj.child(gpath)).to be_nil
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#group?' do
124
+ let(:dir_obj) { obj.child('dir2c') }
125
+
126
+ context 'if the current group is abstract' do
127
+ it 'returns true' do
128
+ expect(obj.group?).to be true
129
+ end
130
+ end
131
+
132
+ context 'if the current group is directory' do
133
+ it 'returns false' do
134
+ expect(dir_obj.group?).to be false
135
+ end
136
+ end
137
+ end
138
+
139
+ describe '#dir?' do
140
+ let(:dir_obj) { obj.child('dir2c') }
141
+
142
+ context 'if the current group is directory' do
143
+ it 'returns true' do
144
+ expect(dir_obj.dir?).to be true
145
+ end
146
+ end
147
+
148
+ context 'if the current group is abstract' do
149
+ it 'returns false' do
150
+ expect(obj.dir?).to be false
151
+ end
152
+ end
153
+ end
154
+
155
+ describe '#group' do
156
+ context 'if the group exists' do
157
+ it 'returns the object' do
158
+ expect(obj.group('group2a')).to be_a(XcodeProject::PBXGroup)
159
+ end
160
+ end
161
+
162
+ context 'if the group doesn\'t exist' do
163
+ it 'returns nil' do
164
+ expect(obj.group('group2a_ghost')).to be nil
165
+ end
166
+ end
167
+ end
168
+
169
+ describe '#file_ref' do
170
+ context 'if the file reference exists' do
171
+ it 'returns the object' do
172
+ expect(obj.file_ref('file2c.m')).to be_a(XcodeProject::PBXFileReference)
173
+ end
174
+ end
175
+
176
+ context 'if the file reference doesn\'t exist' do
177
+ it 'returns nil' do
178
+ expect(obj.file_ref('file2c_ghost.m')).to be nil
179
+ end
180
+ end
181
+ end
182
+
183
+ describe '#add_file_ref' do
184
+ context 'if passed the relative path' do
185
+ it 'adds the file reference, returns the object' do
186
+ expect(obj.send(:add_file_ref, 'dir1b/file2b.m')).to be_a(XcodeProject::PBXFileReference)
187
+ end
188
+ end
189
+
190
+ context 'if passed the absolute path' do
191
+ it 'adds the file reference, returns the object' do
192
+ expect(obj.send(:add_file_ref, "#{example_project_dir}/dir1b/file2b.m")).to be_a(XcodeProject::PBXFileReference)
193
+ end
194
+ end
195
+
196
+ context 'if file reference already exists' do
197
+ it 'new object has same uuid as existing' do
198
+ uuid = obj.file_ref('file2c.m').uuid
199
+ expect(obj.send(:add_file_ref, 'dir1c/file2c.m').uuid).to eql(uuid)
200
+ end
201
+ end
202
+
203
+ context 'if file doesn\'t exit' do
204
+ it 'raise an exception' do
205
+ expect { obj.send(:add_file_ref, 'file2c_ghost.m') }.to raise_exception(XcodeProject::FilePathError)
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#add_group' do
211
+ it 'adds the group, returns the object' do
212
+ group_obj = obj.add_group('group2a_ghost')
213
+ expect(group_obj).to be_a(XcodeProject::PBXGroup)
214
+ expect(group_obj.group?).to be true
215
+ end
216
+ end
217
+
218
+ describe '#add_dir' do
219
+ it 'adds the group, returns the object' do
220
+ group_obj = obj.add_dir('dir1c')
221
+ expect(group_obj).to be_a(XcodeProject::PBXGroup)
222
+ expect(group_obj.dir?).to be true
223
+ end
224
+
225
+ it 'adds all dir\'s children' do
226
+ obj.add_dir('dir1c')
227
+ [
228
+ obj.group('dir1c'),
229
+ obj.group('dir1c/dir2c'),
230
+ obj.file('dir1c/file2c.m')
231
+ ].each do |obj|
232
+ expect(obj).not_to be nil
233
+ end
234
+ end
235
+
236
+ context 'if dir doesn\'t exit' do
237
+ it 'raise an exception' do
238
+ expect { obj.add_dir('dir2c_ghost') }.to raise_exception(XcodeProject::FilePathError)
239
+ end
240
+ end
241
+ end
242
+
243
+ describe '#create_group' do
244
+ context 'if passed a group name' do
245
+ it 'creates and returns the group object' do
246
+ expect(obj.create_group('group2a_ghost')).to be_a(XcodeProject::PBXGroup)
247
+ end
248
+ end
249
+
250
+ context 'if passed a group path' do
251
+ it 'creates missed groups and returns the last group object' do
252
+ [
253
+ 'group2a/group3a_ghost',
254
+ 'group2a_ghost/group3a_ghost',
255
+ 'group2a_ghost/../create_group2a_ghost/./group3a_ghost'
256
+ ].each do |gpath|
257
+ expect(obj.create_group(gpath)).to be_a(XcodeProject::PBXGroup)
258
+ end
259
+ end
260
+ end
261
+
262
+ context 'if group already exists' do
263
+ it 'new object has same uuid as existing' do
264
+ uuid = obj.child('group2a').uuid
265
+ expect(obj.create_group('group2a').uuid).to eql(uuid)
266
+ end
267
+ end
268
+ end
269
+
270
+ describe '#remove_file_ref' do
271
+ context 'if the file reference exists' do
272
+ it 'removes the object' do
273
+ obj.remove_file_ref('group1a/file2c.m')
274
+ expect(obj.file_ref('group1a/file2c.m')).to be nil
275
+ end
276
+ end
277
+
278
+ context 'if the file reference doesn\'t exist' do
279
+ it 'returns nil' do
280
+ expect(obj.remove_file_ref('group1a/file2c_ghost.m')).to be_nil
281
+ end
282
+ end
283
+ end
284
+
285
+ describe '#remove_group' do
286
+ context 'if the group exists' do
287
+ it 'removes the object' do
288
+ obj.remove_group('group2a')
289
+ expect(obj.group('group2a')).to be_nil
290
+ end
291
+ end
292
+
293
+ context 'if the group doesn\'t exist' do
294
+ it 'returns nil' do
295
+ expect(obj.remove_group('group2a_ghost')).to be_nil
296
+ end
297
+ end
298
+ end
299
+
300
+ describe '#remove!' do
301
+ it 'removes the current group' do
302
+ obj.remove!
303
+ expect(root.project.main_group.group('group1a')).to be_nil
304
+ end
305
+ end
306
+
307
+ describe '#absolute_path' do
308
+ let(:dir_obj) { root.project.main_group.group('group1a/dir2c/dir3a') }
309
+
310
+ it 'makes the absolute path' do
311
+ expect([
312
+ 'dir4a/file5a-a.m',
313
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"
314
+ ].map { |path| dir_obj.absolute_path(path) }).to eql([
315
+ Pathname.new("#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"),
316
+ Pathname.new("#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m")
317
+ ])
318
+ end
319
+ end
320
+
321
+ describe '#relative_path' do
322
+ let(:dir_obj) { root.project.main_group.group('group1a/dir2c/dir3a') }
323
+
324
+ it 'makes the relative path' do
325
+ expect([
326
+ 'dir4a/file5a-a.m',
327
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a/file5a-a.m"
328
+ ].map { |path| dir_obj.relative_path(path) }).to eql([
329
+ Pathname.new('dir4a/file5a-a.m'),
330
+ Pathname.new('dir4a/file5a-a.m')
331
+ ])
332
+ end
333
+ end
334
+
335
+ it_behaves_like 'a file node' do
336
+ let(:main_group) do
337
+ root.project.main_group
338
+ end
339
+
340
+ let(:file_nodes_gpaths) do
341
+ [
342
+ 'group1a/dir2c/dir3a/dir4a',
343
+ 'group1a/dir2c/dir3a',
344
+ 'group1a/dir2c',
345
+ 'group1a/group2a',
346
+ 'group1a'
347
+ ]
348
+ end
349
+
350
+ let(:file_nodes_total_paths) do
351
+ [
352
+ "#{example_project_dir}/dir1a/dir2a/dir3a/dir4a",
353
+ "#{example_project_dir}/dir1a/dir2a/dir3a",
354
+ "#{example_project_dir}/dir1c/dir2c",
355
+ example_project_dir,
356
+ example_project_dir
357
+ ]
358
+ end
359
+ end
360
+ end