synx 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +46 -0
  3. data/.travis.yml +20 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +70 -0
  7. data/Rakefile +2 -0
  8. data/bin/synx +18 -0
  9. data/lib/synx.rb +13 -0
  10. data/lib/synx/abstract_object.rb +44 -0
  11. data/lib/synx/pbx_file_reference.rb +70 -0
  12. data/lib/synx/pbx_group.rb +126 -0
  13. data/lib/synx/pbx_native_target.rb +15 -0
  14. data/lib/synx/pbx_variant_group.rb +20 -0
  15. data/lib/synx/project.rb +100 -0
  16. data/lib/synx/tabber.rb +35 -0
  17. data/lib/synx/version.rb +3 -0
  18. data/spec/dummy/dummy.xcodeproj/project.pbxproj +534 -0
  19. data/spec/dummy/dummy.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  20. data/spec/dummy/dummy/AlreadySynced/Core Data.xcdatamodeld/.xccurrentversion +8 -0
  21. data/spec/dummy/dummy/AlreadySynced/Core Data.xcdatamodeld/Core Data 2.xcdatamodel/contents +4 -0
  22. data/spec/dummy/dummy/AlreadySynced/Core Data.xcdatamodeld/Core Data 3.xcdatamodel/contents +4 -0
  23. data/spec/dummy/dummy/AlreadySynced/Core Data.xcdatamodeld/Core Data 4.xcdatamodel/contents +4 -0
  24. data/spec/dummy/dummy/AlreadySynced/Core Data.xcdatamodeld/Core Data.xcdatamodel/contents +4 -0
  25. data/spec/dummy/dummy/AlreadySynced/FolderNotInXcodeProj/AnotherFileNotInXcodeProj.h +0 -0
  26. data/spec/dummy/dummy/AlreadySynced/FolderNotInXcodeProj/NSObject+abc.h +13 -0
  27. data/spec/dummy/dummy/AlreadySynced/FolderNotInXcodeProj/NSObject+abc.m +13 -0
  28. data/spec/dummy/dummy/AlreadySynced/FolderNotInXcodeProj/Wowwww.h +13 -0
  29. data/spec/dummy/dummy/AlreadySynced/FolderNotInXcodeProj/Wowwww.m +13 -0
  30. data/spec/dummy/dummy/AlreadySynced/Woot.h +13 -0
  31. data/spec/dummy/dummy/AlreadySynced/Woot.m +13 -0
  32. data/spec/dummy/dummy/AlreadySynced/stuff.xml +0 -0
  33. data/spec/dummy/dummy/FileNotInXcodeProj.h +0 -0
  34. data/spec/dummy/dummy/ManyFiles.h +13 -0
  35. data/spec/dummy/dummy/ManyFiles.m +13 -0
  36. data/spec/dummy/dummy/Wow.h +13 -0
  37. data/spec/dummy/dummy/Wow.m +13 -0
  38. data/spec/dummy/dummy/data.json +0 -0
  39. data/spec/dummy/dummy/dummy-Prefix.pch +9 -0
  40. data/spec/dummy/dummy/dummy.h +13 -0
  41. data/spec/dummy/dummy/dummy.m +13 -0
  42. data/spec/dummy/dummy/image-not-in-xcodeproj.png +0 -0
  43. data/spec/dummy/dummy/image.png +0 -0
  44. data/spec/dummy/dummyTests/dummyTests-Info.plist +22 -0
  45. data/spec/dummy/dummyTests/dummyTests-prefix.pch +15 -0
  46. data/spec/dummy/dummyTests/dummyTests.m +34 -0
  47. data/spec/dummy/dummyTests/en.lproj/InfoPlist.strings +2 -0
  48. data/spec/spec_helper.rb +11 -0
  49. data/spec/synx/expected_file_structure.yml +44 -0
  50. data/spec/synx/expected_group_structure.yml +37 -0
  51. data/spec/synx/project_spec.rb +218 -0
  52. data/spec/synx/tabber_spec.rb +64 -0
  53. data/synx.gemspec +33 -0
  54. metadata +251 -0
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Workspace
3
+ version = "1.0">
4
+ <FileRef
5
+ location = "self:dummy.xcodeproj">
6
+ </FileRef>
7
+ </Workspace>
@@ -0,0 +1,8 @@
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>_XCCurrentVersionName</key>
6
+ <string>Core Data 3.xcdatamodel</string>
7
+ </dict>
8
+ </plist>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5064" systemVersion="13C64" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
3
+ <elements/>
4
+ </model>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5064" systemVersion="13C64" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
3
+ <elements/>
4
+ </model>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5064" systemVersion="13C64" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
3
+ <elements/>
4
+ </model>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="5064" systemVersion="13C64" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
3
+ <elements/>
4
+ </model>
@@ -0,0 +1,13 @@
1
+ //
2
+ // NSObject+abc.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface NSObject (abc)
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // NSObject+abc.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "NSObject+abc.h"
10
+
11
+ @implementation NSObject (abc)
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Wowwww.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface Wowwww : NSObject
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Wowwww.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "Wowwww.h"
10
+
11
+ @implementation Wowwww
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Woot.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface Woot : NSObject
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Woot.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "Woot.h"
10
+
11
+ @implementation Woot
12
+
13
+ @end
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ //
2
+ // ManyFiles.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface ManyFiles : NSObject
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // ManyFiles.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "ManyFiles.h"
10
+
11
+ @implementation ManyFiles
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Wow.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface Wow : NSObject
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // Wow.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/9/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "Wow.h"
10
+
11
+ @implementation Wow
12
+
13
+ @end
File without changes
@@ -0,0 +1,9 @@
1
+ //
2
+ // Prefix header
3
+ //
4
+ // The contents of this file are implicitly included at the beginning of every source file.
5
+ //
6
+
7
+ #ifdef __OBJC__
8
+ #import <Foundation/Foundation.h>
9
+ #endif
@@ -0,0 +1,13 @@
1
+ //
2
+ // dummy.h
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 4/27/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ @interface dummy : NSObject
12
+
13
+ @end
@@ -0,0 +1,13 @@
1
+ //
2
+ // dummy.m
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 4/27/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import "dummy.h"
10
+
11
+ @implementation dummy
12
+
13
+ @end
File without changes
File without changes
@@ -0,0 +1,22 @@
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>marklarr.${PRODUCT_NAME:rfc1034identifier}</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundlePackageType</key>
14
+ <string>BNDL</string>
15
+ <key>CFBundleShortVersionString</key>
16
+ <string>1.0</string>
17
+ <key>CFBundleSignature</key>
18
+ <string>????</string>
19
+ <key>CFBundleVersion</key>
20
+ <string>1</string>
21
+ </dict>
22
+ </plist>
@@ -0,0 +1,15 @@
1
+ //
2
+ // dummyTests-prefix.pch
3
+ // dummy
4
+ //
5
+ // Created by Mark Larsen on 5/13/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #ifndef dummy_dummyTests_prefix_pch
10
+ #define dummy_dummyTests_prefix_pch
11
+
12
+ // Include any system framework and library headers here that should be included in all compilation units.
13
+ // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
14
+
15
+ #endif
@@ -0,0 +1,34 @@
1
+ //
2
+ // dummyTests.m
3
+ // dummyTests
4
+ //
5
+ // Created by Mark Larsen on 4/27/14.
6
+ // Copyright (c) 2014 marklarr. All rights reserved.
7
+ //
8
+
9
+ #import <XCTest/XCTest.h>
10
+
11
+ @interface dummyTests : XCTestCase
12
+
13
+ @end
14
+
15
+ @implementation dummyTests
16
+
17
+ - (void)setUp
18
+ {
19
+ [super setUp];
20
+ // Put setup code here. This method is called before the invocation of each test method in the class.
21
+ }
22
+
23
+ - (void)tearDown
24
+ {
25
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
26
+ [super tearDown];
27
+ }
28
+
29
+ - (void)testExample
30
+ {
31
+ XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32
+ }
33
+
34
+ @end
@@ -0,0 +1,2 @@
1
+ /* Localized versions of Info.plist keys */
2
+
@@ -0,0 +1,11 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'synx'
5
+ require 'pry'
6
+ require 'coveralls'
7
+
8
+ Coveralls.wear!
9
+
10
+ RSpec.configure do |config|
11
+ end
@@ -0,0 +1,44 @@
1
+ dummy:
2
+ Resources:
3
+ image.png:
4
+ data.json:
5
+ image-not-in-xcodeproj.png:
6
+ AlreadySynced:
7
+ Core Data.xcdatamodeld:
8
+ Core Data.xcdatamodel:
9
+ contents:
10
+ Core Data 2.xcdatamodel:
11
+ contents:
12
+ Core Data 3.xcdatamodel:
13
+ contents:
14
+ Core Data 4.xcdatamodel:
15
+ contents:
16
+ FolderNotInXcodeProj:
17
+ AnotherFileNotInXcodeProj.h:
18
+ NSObject+abc.h:
19
+ NSObject+abc.m:
20
+ Woot.h:
21
+ Woot.m:
22
+ stuff.xml:
23
+ GroupThatDoubleReferencesFile:
24
+ ManyFiles.h:
25
+ ManyFiles.m:
26
+ Supporting Files:
27
+ dummy-Prefix.pch:
28
+ dummy.h:
29
+ dummy.m:
30
+ FileNotInXcodeProj.h:
31
+ SuchGroup:
32
+ Wow.h:
33
+ Wow.m:
34
+ VeryChildGroup:
35
+ Wowwww.h:
36
+ Wowwww.m:
37
+ dummyTests:
38
+ Other Files:
39
+ en.lproj:
40
+ InfoPlist.strings:
41
+ Supporting Files:
42
+ dummyTests-Prefix.pch:
43
+ dummyTests-Info.plist:
44
+ dummyTests.m:
@@ -0,0 +1,37 @@
1
+ dummy:
2
+ Resources:
3
+ image.png:
4
+ AlreadySynced:
5
+ Core Data.xcdatamodeld:
6
+ Core Data.xcdatamodel:
7
+ contents:
8
+ Core Data 2.xcdatamodel:
9
+ contents:
10
+ Core Data 3.xcdatamodel:
11
+ contents:
12
+ Core Data 4.xcdatamodel:
13
+ contents:
14
+ NSObject+abc.h:
15
+ NSObject+abc.m:
16
+ Woot.h:
17
+ Woot.m:
18
+ GroupThatDoubleReferencesFile:
19
+ ManyFiles.h:
20
+ ManyFiles.m:
21
+ Supporting Files:
22
+ dummy-Prefix.pch:
23
+ dummy.h:
24
+ dummy.m:
25
+ SuchGroup:
26
+ Wow.h:
27
+ Wow.m:
28
+ VeryChildGroup:
29
+ Wowwww.h:
30
+ Wowwww.m:
31
+ dummyTests:
32
+ Other Files:
33
+ InfoPlist.strings:
34
+ Supporting Files:
35
+ dummyTests-Prefix.pch:
36
+ dummyTests-Info.plist:
37
+ dummyTests.m:
@@ -0,0 +1,218 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ require 'fileutils'
4
+ require 'pathname'
5
+ require 'yaml'
6
+
7
+ class Hash
8
+ # Return a hash that includes everything but the given keys. This is useful for
9
+ # limiting a set of parameters to everything but a few known toggles:
10
+ #
11
+ # @person.update_attributes(params[:person].except(:admin))
12
+ #
13
+ # If the receiver responds to +convert_key+, the method is called on each of the
14
+ # arguments. This allows +except+ to play nice with hashes with indifferent access
15
+ # for instance:
16
+ #
17
+ # {:a => 1}.with_indifferent_access.except(:a) # => {}
18
+ # {:a => 1}.with_indifferent_access.except("a") # => {}
19
+ #
20
+ def except(*keys)
21
+ dup.except!(*keys)
22
+ end
23
+
24
+ # Replaces the hash without the given keys.
25
+ def except!(*keys)
26
+ keys.each { |key| delete(key) }
27
+ self
28
+ end
29
+ end
30
+
31
+ describe Synx::Project do
32
+
33
+ DUMMY_SYNX_PATH = File.join(File.dirname(__FILE__), '..', 'dummy')
34
+ DUMMY_SYNX_TEST_PATH = File.join(File.dirname(__FILE__), '..', 'test_dummy')
35
+ DUMMY_SYNX_TEST_PROJECT_PATH = File.join(DUMMY_SYNX_TEST_PATH, 'dummy.xcodeproj')
36
+
37
+ before(:all) do
38
+ FileUtils.rm_rf(DUMMY_SYNX_TEST_PATH)
39
+ FileUtils.cp_r(DUMMY_SYNX_PATH, DUMMY_SYNX_TEST_PATH)
40
+ DUMMY_SYNX_TEST_PROJECT = Synx::Project.open(DUMMY_SYNX_TEST_PROJECT_PATH)
41
+ end
42
+
43
+ describe "#sync" do
44
+
45
+ def verify_group_structure(group, expected_structure)
46
+ expected_structure.each do |object_name, object_children|
47
+ failure_message = "expected group `#{group.basename}` to have child `#{object_name}`"
48
+ object = group.children.detect { |child| child.basename == object_name }
49
+ expect(group).to_not be_nil, failure_message
50
+
51
+ if object.instance_of?(Xcodeproj::Project::Object::PBXGroup)
52
+ object_children ||= {}
53
+ failure_message = "Expected #{object_name} to have #{object_children.count} children, found #{object.children.count}"
54
+ expect(object_children.count).to eq(object.children.count), failure_message
55
+ verify_group_structure(object, object_children) if object_children.count > 0
56
+ end
57
+ end
58
+ end
59
+
60
+ def verify_file_structure(dir_pathname, expected_structure)
61
+ expected_structure.each do |entry_name, entry_entries|
62
+ entry_pathname = dir_pathname + entry_name
63
+ expect(File.exist?(entry_pathname) || Dir.exists?(entry_pathname)).to be(true), "Expected #{entry_pathname} to exist"
64
+
65
+ if File.directory?(entry_pathname)
66
+ entry_entries ||= {}
67
+ # '.' and '..' show up in entries, so add 2
68
+ failure_message = "Expected #{entry_pathname} to have #{entry_entries.count} children, found #{entry_pathname.entries.count - 2}"
69
+ expect(entry_entries.count + 2).to eq(entry_pathname.entries.count), failure_message
70
+ verify_file_structure(entry_pathname, entry_entries) if entry_entries.count > 0
71
+ end
72
+ end
73
+ end
74
+
75
+ def expected_file_structure
76
+ YAML::load_file(File.join(File.dirname(__FILE__), "expected_file_structure.yml"))
77
+ end
78
+
79
+ def expected_group_structure
80
+ YAML::load_file(File.join(File.dirname(__FILE__), "expected_group_structure.yml"))
81
+ end
82
+
83
+ describe "with no additional options" do
84
+
85
+ before(:all) do
86
+ DUMMY_SYNX_TEST_PROJECT.sync
87
+ end
88
+
89
+ it "should have the correct physical file structure" do
90
+ verify_file_structure(Pathname(DUMMY_SYNX_TEST_PROJECT_PATH).parent, expected_file_structure)
91
+ end
92
+
93
+ it "should not have modified the Xcode group structure, except for fixing double file references" do
94
+ verify_group_structure(DUMMY_SYNX_TEST_PROJECT.main_group, expected_group_structure)
95
+ end
96
+
97
+ it "should have updated the pch and info.plist build setting paths" do
98
+ # dummy target
99
+ DUMMY_SYNX_TEST_PROJECT.targets.first.each_build_settings do |bs|
100
+ expect(bs["GCC_PREFIX_HEADER"]).to eq("dummy/Supporting Files/dummy-Prefix.pch")
101
+ expect(bs["INFOPLIST_FILE"]).to be_nil
102
+ end
103
+
104
+ # dummyTests target
105
+ DUMMY_SYNX_TEST_PROJECT.targets.last.each_build_settings do |bs|
106
+ expect(bs["GCC_PREFIX_HEADER"]).to eq("dummyTests/Supporting Files/dummyTests-Prefix.pch")
107
+ expect(bs["INFOPLIST_FILE"]).to eq("dummyTests/Supporting Files/dummyTests-Info.plist")
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "with the prune option toggled" do
113
+
114
+ before(:all) do
115
+ DUMMY_SYNX_TEST_PROJECT.sync(:prune => true)
116
+ end
117
+
118
+ it "should remove unreferenced images and source files if the prune option is toggled" do
119
+ expected_file_structure_with_removals = expected_file_structure
120
+ expected_file_structure_with_removals["dummy"].except!("image-not-in-xcodeproj.png")
121
+ expected_file_structure_with_removals["dummy"].except!("FileNotInXcodeProj.h")
122
+ expected_file_structure_with_removals["dummy"]["AlreadySynced"]["FolderNotInXcodeProj"].except!("AnotherFileNotInXcodeProj.h")
123
+ verify_file_structure(Pathname(DUMMY_SYNX_TEST_PROJECT_PATH).parent, expected_file_structure_with_removals)
124
+ end
125
+
126
+ it "should not have modified the Xcode group structure, except for fixing double file references" do
127
+ verify_group_structure(DUMMY_SYNX_TEST_PROJECT.main_group, expected_group_structure)
128
+ end
129
+ end
130
+
131
+ describe "with the no_default_exclusions option toggled" do
132
+
133
+ before(:all) do
134
+ DUMMY_SYNX_TEST_PROJECT.sync(:no_default_exclusions => true)
135
+ end
136
+
137
+ it "should have an empty array for default exclusions" do
138
+ expect(DUMMY_SYNX_TEST_PROJECT.group_exclusions.count).to eq(0)
139
+ end
140
+ end
141
+
142
+ describe "with group_exclusions provided as options" do
143
+
144
+ before(:all) do
145
+ DUMMY_SYNX_TEST_PROJECT.sync(:group_exclusions => %W(/dummy /dummy/SuchGroup/VeryChildGroup))
146
+ end
147
+
148
+ it "should add the group exclusions to the array" do
149
+ expect(DUMMY_SYNX_TEST_PROJECT.group_exclusions.sort).to eq(%W(/Libraries /Products /Frameworks /dummy /dummy/SuchGroup/VeryChildGroup).sort)
150
+ end
151
+ end
152
+
153
+ end
154
+
155
+ describe "group_exclusions=" do
156
+
157
+ it "should raise an IndexError if any of the groups do not exist" do
158
+ expect { DUMMY_SYNX_TEST_PROJECT.group_exclusions = %W(/dummy /dummy/DoesntExist) }.to raise_error(IndexError)
159
+ end
160
+
161
+ it "should be fine if the groups all exist" do
162
+ group_exclusions = %W(/dummy /dummy/GroupThatDoubleReferencesFile /dummy/SuchGroup/VeryChildGroup)
163
+ DUMMY_SYNX_TEST_PROJECT.group_exclusions = group_exclusions
164
+
165
+ expect(DUMMY_SYNX_TEST_PROJECT.group_exclusions).to eq(group_exclusions)
166
+ end
167
+ end
168
+
169
+ describe "#root_pathname" do
170
+
171
+ it "should return the pathname to the directory that the .pbxproj file is inside" do
172
+ expected = Pathname(File.join(File.dirname(__FILE__), '..', 'test_dummy'))
173
+ DUMMY_SYNX_TEST_PROJECT.send(:root_pathname).realpath.should eq(expected.realpath)
174
+ end
175
+ end
176
+
177
+ describe "#work_root_pathname" do
178
+
179
+ before(:each) { DUMMY_SYNX_TEST_PROJECT.instance_variable_set("@work_root_pathname", nil) }
180
+
181
+ it "should return the pathname to the directory synxchronize will do its work in" do
182
+ expected = Pathname(Synx::Project.const_get(:SYNXRONIZE_DIR)) + "test_dummy"
183
+ DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname).realpath.should eq(expected.realpath)
184
+ end
185
+
186
+ it "should start fresh by removing any existing directory at work_root_pathname" do
187
+ Pathname.any_instance.stub(:exist?).and_return(true)
188
+ expect(FileUtils).to receive(:rm_rf)
189
+
190
+ DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname)
191
+ end
192
+
193
+ it "should create a directory at work_root_pathname" do
194
+ expect_any_instance_of(Pathname).to receive(:mkpath)
195
+ DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname)
196
+ end
197
+
198
+ it "should be an idempotent operation but return the same value through memoization" do
199
+ pathname = DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname)
200
+ expect(FileUtils).to_not receive(:rm_rf)
201
+ expect_any_instance_of(Pathname).to_not receive(:exist?)
202
+ expect_any_instance_of(Pathname).to_not receive(:mkpath)
203
+ expect(DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname)).to be(pathname)
204
+ end
205
+ end
206
+
207
+ describe "#pathname_to_work_pathname" do
208
+
209
+ it "should return the path in work_root_pathname that is relatively equivalent to root_pathname" do
210
+ pathname = DUMMY_SYNX_TEST_PROJECT.send(:root_pathname) + "some" + "path" + "to" + "thing"
211
+
212
+ value = DUMMY_SYNX_TEST_PROJECT.send(:pathname_to_work_pathname, pathname)
213
+ expected = DUMMY_SYNX_TEST_PROJECT.send(:work_root_pathname) + "some" + "path" + "to" + "thing"
214
+
215
+ expect(value).to eq(expected)
216
+ end
217
+ end
218
+ end