zerg_xcode 0.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 (46) hide show
  1. data/CHANGELOG +1 -0
  2. data/LICENSE +21 -0
  3. data/Manifest +44 -0
  4. data/README.textile +124 -0
  5. data/RUBYFORGE +40 -0
  6. data/Rakefile +27 -0
  7. data/bin/zerg-xcode +7 -0
  8. data/lib/zerg_xcode/file_format/archiver.rb +87 -0
  9. data/lib/zerg_xcode/file_format/encoder.rb +40 -0
  10. data/lib/zerg_xcode/file_format/lexer.rb +60 -0
  11. data/lib/zerg_xcode/file_format/parser.rb +46 -0
  12. data/lib/zerg_xcode/file_format/paths.rb +44 -0
  13. data/lib/zerg_xcode/objects/pbx_build_file.rb +27 -0
  14. data/lib/zerg_xcode/objects/pbx_native_target.rb +19 -0
  15. data/lib/zerg_xcode/objects/pbx_project.rb +60 -0
  16. data/lib/zerg_xcode/objects/xcode_object.rb +144 -0
  17. data/lib/zerg_xcode/plugins/core/core.rb +36 -0
  18. data/lib/zerg_xcode/plugins/help.rb +30 -0
  19. data/lib/zerg_xcode/plugins/import.rb +19 -0
  20. data/lib/zerg_xcode/plugins/irb.rb +22 -0
  21. data/lib/zerg_xcode/plugins/ls.rb +27 -0
  22. data/lib/zerg_xcode/plugins/retarget.rb +90 -0
  23. data/lib/zerg_xcode/shortcuts.rb +22 -0
  24. data/lib/zerg_xcode.rb +17 -0
  25. data/test/file_format/archiver_test.rb +70 -0
  26. data/test/file_format/encoder_test.rb +10 -0
  27. data/test/file_format/lexer_test.rb +56 -0
  28. data/test/file_format/parser_test.rb +44 -0
  29. data/test/file_format/path_test.rb +40 -0
  30. data/test/objects/pbx_build_file_test.rb +38 -0
  31. data/test/objects/pbx_native_target_test.rb +31 -0
  32. data/test/objects/pbx_project_test.rb +62 -0
  33. data/test/objects/xcode_object_test.rb +117 -0
  34. data/test/plugins/core/core_test.rb +32 -0
  35. data/test/plugins/import_test.rb +22 -0
  36. data/test/plugins/irb_test.rb +30 -0
  37. data/test/plugins/ls_test.rb +43 -0
  38. data/test/plugins/retarget_test.rb +65 -0
  39. data/test/plugins/test_helper.rb +21 -0
  40. data/test/shortcuts_test.rb +18 -0
  41. data/testdata/TestApp/TestApp.xcodeproj/project.pbxproj +328 -0
  42. data/testdata/ZergSupport.xcodeproj/project.pbxproj +930 -0
  43. data/testdata/project.pbxproj +250 -0
  44. data/testdata/project.pbxproj.compat +320 -0
  45. data/zerg_xcode.gemspec +34 -0
  46. metadata +137 -0
@@ -0,0 +1,31 @@
1
+ require 'test/unit'
2
+
3
+ require 'zerg_xcode'
4
+
5
+ class PBXNativeTargetTest < Test::Unit::TestCase
6
+ PBXNativeTarget = ZergXcode::Objects::PBXNativeTarget
7
+
8
+ def test_all_files
9
+ golden_list = [
10
+ ["PBXResourcesBuildPhase", "MainWindow.xib"],
11
+ ["PBXResourcesBuildPhase", "TestAppViewController.xib"],
12
+ ["PBXSourcesBuildPhase", "main.m"],
13
+ ["PBXSourcesBuildPhase", "TestAppAppDelegate.m"],
14
+ ["PBXSourcesBuildPhase", "TestAppViewController.m"],
15
+ ["PBXFrameworksBuildPhase",
16
+ "System/Library/Frameworks/Foundation.framework"],
17
+ ["PBXFrameworksBuildPhase",
18
+ "System/Library/Frameworks/UIKit.framework"],
19
+ ["PBXFrameworksBuildPhase",
20
+ "System/Library/Frameworks/CoreGraphics.framework"],
21
+ ]
22
+
23
+ project = ZergXcode.load('testdata/project.pbxproj')
24
+ assert_equal PBXNativeTarget, project['targets'].first.class
25
+ files = project['targets'].first.all_files
26
+ file_list = files.map do |file|
27
+ [file[:phase]['isa'], file[:object]['path']]
28
+ end
29
+ assert_equal golden_list.sort, file_list.sort
30
+ end
31
+ end
@@ -0,0 +1,62 @@
1
+ require 'test/unit'
2
+
3
+ require 'zerg_xcode'
4
+
5
+ require 'rubygems'
6
+ require 'flexmock'
7
+
8
+
9
+ class PBXProjectTest < Test::Unit::TestCase
10
+ PBXProject = ZergXcode::Objects::PBXProject
11
+ def test_all_files_small
12
+ golden_list = [
13
+ ["./Classes/TestAppAppDelegate.h", "sourcecode.c.h"],
14
+ ["./Classes/TestAppAppDelegate.m", "sourcecode.c.objc"],
15
+ ["./Classes/TestAppViewController.h", "sourcecode.c.h"],
16
+ ["./Classes/TestAppViewController.m", "sourcecode.c.objc"],
17
+ ["./TestApp_Prefix.pch", "sourcecode.c.h"],
18
+ ["./main.m", "sourcecode.c.objc"],
19
+ ["./TestAppViewController.xib", "file.xib"],
20
+ ["./MainWindow.xib", "file.xib"],
21
+ ["./Info.plist", "text.plist.xml"],
22
+ ["SDKROOT/System/Library/Frameworks/UIKit.framework",
23
+ "wrapper.framework"],
24
+ ["SDKROOT/System/Library/Frameworks/Foundation.framework",
25
+ "wrapper.framework"],
26
+ ["SDKROOT/System/Library/Frameworks/CoreGraphics.framework",
27
+ "wrapper.framework"],
28
+ ["BUILT_PRODUCTS_DIR/TestApp.app", nil],
29
+ ]
30
+
31
+ project = ZergXcode.load('testdata/project.pbxproj')
32
+ assert_equal PBXProject, project.class
33
+ files = project.all_files
34
+ file_list = files.map { |f| [f[:path], f[:object]['lastKnownFileType']] }
35
+ assert_equal golden_list.sort, file_list.sort
36
+ end
37
+
38
+ def test_all_files_large
39
+ golden_entries = [
40
+ ["./ZergSupport/FormatSupport/ZNFormFieldFormatter+Snake2LCamel.m",
41
+ "sourcecode.c.objc"],
42
+ ["./ZergSupport/ModelSupport/ZNModelDefinitionAttributeTest.m",
43
+ "sourcecode.c.objc"],
44
+ ["./ZergSupport/TestSupport/TestSupport.h", "sourcecode.c.h"],
45
+ ["./ZergSupport/TestSupport/GTM/GTMDefines.h", "sourcecode.c.h"],
46
+ ["./ZergSupport/WebSupport/ZNHttpRequest.m", "sourcecode.c.objc"],
47
+ ]
48
+ files = ZergXcode.load('testdata/ZergSupport').all_files
49
+ file_list = files.map { |f| [f[:path], f[:object]['lastKnownFileType']] }
50
+ golden_entries.each do |entry|
51
+ assert file_list.include?(entry), "Missing #{entry.inspect}"
52
+ end
53
+ end
54
+
55
+ def test_save
56
+ project = ZergXcode.load('testdata')
57
+ flexmock(ZergXcode).should_receive(:dump).
58
+ with(project, 'testdata/project.pbxproj').
59
+ and_return(nil)
60
+ project.save!
61
+ end
62
+ end
@@ -0,0 +1,117 @@
1
+ require 'set'
2
+ require 'test/unit'
3
+
4
+ require 'zerg_xcode'
5
+
6
+ class ObjectTest < Test::Unit::TestCase
7
+ XcodeObject = ZergXcode::XcodeObject
8
+ PBXProject = ZergXcode::Objects::PBXProject
9
+
10
+ def setup
11
+ @sub1 = XcodeObject.new :array => ['a', 'b', 'c'], :string => 's'
12
+ @sub1.archive_id = 39
13
+ @sub2 = XcodeObject.new :hash => { :k => 'v', :k2 => 'v2' }, :sub1 => @sub1
14
+ @sub2.archive_id = 42
15
+ @root = XcodeObject.new :sub1 => @sub1, :sub2 => @sub2
16
+ @root.archive_id = 49
17
+ @root.version = 45
18
+ end
19
+
20
+ def test_readonly_visit
21
+ golden_visited = [
22
+ [49, 'sub1', @sub1],
23
+ [39, 'array', @sub1[:array]],
24
+ [39, '0', 'a'],
25
+ [39, '1', 'b'],
26
+ [39, '2', 'c'],
27
+ [39, 'string', 's'],
28
+ [49, 'sub2', @sub2],
29
+ [42, 'hash', @sub2[:hash]],
30
+ [42, 'k', 'v'],
31
+ [42, 'k2', 'v2'],
32
+ [42, 'sub1', @sub1],
33
+ ]
34
+
35
+ visited = []
36
+ visited_objects = Set.new
37
+ @root.visit do |object, parent, key, value|
38
+ assert_equal value, parent[key], 'Parent/Key/Value check'
39
+
40
+ visited << [object.archive_id, key.to_s, value]
41
+ next true unless value.kind_of? XcodeObject
42
+ next false if visited_objects.include? value
43
+ visited_objects << value
44
+ next true
45
+ end
46
+ assert_equal golden_visited.sort, visited.sort
47
+ end
48
+
49
+ def test_mutating_visit
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, '3', 'a'],
57
+ [39, '4', 'b'],
58
+ [39, '5', 'c'],
59
+ [39, 'string', 's'],
60
+ [49, 'sub2', @sub2],
61
+ [42, 'hash', @sub2[:hash]],
62
+ [42, 'k', 'v'],
63
+ [42, 'k2', 'v2'],
64
+ [42, 'sub1', @sub1],
65
+ ]
66
+
67
+ visited = []
68
+ visited_objects = Set.new
69
+ @root.visit do |object, parent, key, value|
70
+ assert_equal value, parent[key], 'Parent/Key/Value check'
71
+
72
+ visited << [object.archive_id, key.to_s, value]
73
+ case value
74
+ when XcodeObject
75
+ next false if visited_objects.include? value
76
+ visited_objects << value
77
+ next true
78
+ when Array, String
79
+ next value * 2
80
+ when Hash
81
+ next true
82
+ end
83
+ end
84
+
85
+ assert_equal golden_visited.sort, visited.sort
86
+ assert_equal @sub1[:array], ['aa', 'bb', 'cc', 'aa', 'bb', 'cc']
87
+ assert_equal @sub1[:string], 'ss'
88
+ end
89
+
90
+ def test_deep_copy
91
+ root = XcodeObject.from @root
92
+ assert_equal root[:sub2][:sub1], root[:sub1], 'Deep copy tracks objects'
93
+
94
+ root[:sub1] = 'break'
95
+ assert @root[:sub1] != 'break', 'Deep copy duplicates object attributes'
96
+ root[:sub2][:hash][:k] = 'break'
97
+ assert @root[:sub2][:hash] != 'break', 'Deep copy duplicates hashes'
98
+ root[:sub2][:sub1][:array][0] = 'break'
99
+ assert @root[:sub2][:sub1][:array][0] != 'break',
100
+ 'Deep copy duplicates hashes'
101
+ end
102
+
103
+ def test_messed_up_inheritance
104
+ assert_equal XcodeObject, @root.class
105
+
106
+ p = XcodeObject.new 'isa' => 'PBXProject', 'name' => 'awesome'
107
+ assert_equal PBXProject, p.class
108
+
109
+ root = XcodeObject.from @root
110
+ assert_equal XcodeObject, root.class, 'After deep copy'
111
+ assert_equal PBXProject, XcodeObject.from(p).class, 'After deep copy'
112
+
113
+ p = PBXProject.new 'name' => 'boo'
114
+ assert_equal 'PBXProject', p['isa'], 'Subclass creation does not set isa.'
115
+ assert_equal 'boo', p['name'], 'Subclass creation corrupts attributes'
116
+ end
117
+ end
@@ -0,0 +1,32 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'test/plugins/test_helper.rb'
4
+
5
+ require 'zerg_xcode'
6
+
7
+ class Plugins::CoreTest < Test::Unit::TestCase
8
+ include Plugins::TestHelper
9
+
10
+ def test_all
11
+ assert ZergXcode::Plugins.all.include?('ls'), 'Incomplete list'
12
+ end
13
+
14
+ def test_get
15
+ ls_instance = ZergXcode::Plugins.get 'ls'
16
+ ls_class = ZergXcode::Plugins::Ls
17
+ assert ls_instance.kind_of?(ls_class), 'Get retrieves wrong object'
18
+ end
19
+
20
+ def test_help
21
+ help = ZergXcode::Plugins.help 'ls'
22
+ assert help[:short], 'Help object does not contain short description'
23
+ assert help[:long], 'Help object does not contain long description'
24
+ end
25
+
26
+ def test_run
27
+ help_output = capture_output { ZergXcode::Plugins.run('help', []) }
28
+
29
+ assert help_output.index('Xcode Project Modifier brought to you by '),
30
+ 'The result of running help does not match the expected result'
31
+ end
32
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'test/plugins/test_helper.rb'
3
+
4
+ require 'zerg_xcode'
5
+
6
+ require 'rubygems'
7
+ require 'flexmock/test_unit'
8
+
9
+ module Plugins; end
10
+
11
+ class Plugins::ImportTest < Test::Unit::TestCase
12
+ include Plugins::TestHelper
13
+
14
+ def setup
15
+ super
16
+ @plugin = ZergXcode.plugin 'import'
17
+ end
18
+
19
+ def test_plugin
20
+ flunk
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ require 'test/unit'
2
+ require 'test/plugins/test_helper.rb'
3
+
4
+ require 'zerg_xcode'
5
+
6
+ require 'rubygems'
7
+ require 'flexmock/test_unit'
8
+ require 'irb'
9
+
10
+ module Plugins; end
11
+
12
+ class Plugins::IrbTest < Test::Unit::TestCase
13
+ include Plugins::TestHelper
14
+
15
+ def setup
16
+ super
17
+ @plugin = ZergXcode.plugin 'irb'
18
+ end
19
+
20
+ def test_irb_call
21
+ test_project = ZergXcode.load '.'
22
+
23
+ flexmock(IRB).should_receive(:start).and_return(nil)
24
+ output = capture_output { @plugin.run([]) }
25
+ assert_equal test_project.attrs, $p.attrs, 'Loaded incorrect project'
26
+ assert output.index("'quit'"), 'Missing instructions on how to leave IRB'
27
+ assert_equal "\n", output[-1, 1], 'Instructions missing trailing newline'
28
+ $p = nil
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'test/plugins/test_helper.rb'
4
+
5
+ require 'zerg_xcode'
6
+
7
+ module Plugins; end
8
+
9
+ class Plugins::LsTest < Test::Unit::TestCase
10
+ include Plugins::TestHelper
11
+
12
+ def setup
13
+ @plugin = ZergXcode.plugin 'ls'
14
+ end
15
+
16
+ def test_list
17
+ golden_list = [
18
+ ["./Classes/TestAppAppDelegate.h", "sourcecode.c.h"],
19
+ ["./Classes/TestAppAppDelegate.m", "sourcecode.c.objc"],
20
+ ["./Classes/TestAppViewController.h", "sourcecode.c.h"],
21
+ ["./Classes/TestAppViewController.m", "sourcecode.c.objc"],
22
+ ["./TestApp_Prefix.pch", "sourcecode.c.h"],
23
+ ["./main.m", "sourcecode.c.objc"],
24
+ ["./TestAppViewController.xib", "file.xib"],
25
+ ["./MainWindow.xib", "file.xib"],
26
+ ["./Info.plist", "text.plist.xml"],
27
+ ["SDKROOT/System/Library/Frameworks/UIKit.framework",
28
+ "wrapper.framework"],
29
+ ["SDKROOT/System/Library/Frameworks/Foundation.framework",
30
+ "wrapper.framework"],
31
+ ["SDKROOT/System/Library/Frameworks/CoreGraphics.framework",
32
+ "wrapper.framework"],
33
+ ["BUILT_PRODUCTS_DIR/TestApp.app", nil]]
34
+ file_list = @plugin.list_for 'testdata/project.pbxproj'
35
+ assert_equal golden_list.sort, file_list.sort
36
+ end
37
+
38
+ def test_run
39
+ output = capture_output { @plugin.run(['testdata']) }
40
+ assert_equal "sourcecode.c.h ./Classes/TestAppAppDelegate.h",
41
+ output[/^(.*?)$/]
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'test/plugins/test_helper.rb'
4
+
5
+ require 'zerg_xcode'
6
+
7
+ require 'rubygems'
8
+ require 'flexmock'
9
+
10
+ module Plugins; end
11
+
12
+ class Plugins::RetargetTest < Test::Unit::TestCase
13
+ def setup
14
+ super
15
+ @plugin = ZergXcode.plugin 'retarget'
16
+ @proj = ZergXcode.load 'testdata/TestApp/TestApp.xcodeproj'
17
+ @regexp = /^Test.*\.[^a]/
18
+
19
+ @golden_list_for_app = [
20
+ ["PBXResourcesBuildPhase", "MainWindow.xib"],
21
+ ["PBXSourcesBuildPhase", "main.m"],
22
+ ["PBXFrameworksBuildPhase",
23
+ "System/Library/Frameworks/Foundation.framework"],
24
+ ["PBXFrameworksBuildPhase",
25
+ "System/Library/Frameworks/UIKit.framework"],
26
+ ["PBXFrameworksBuildPhase",
27
+ "System/Library/Frameworks/CoreGraphics.framework"],
28
+ ]
29
+ @golden_list_for_lib = [
30
+ ["PBXHeadersBuildPhase", "TestAppAppDelegate.h"],
31
+ ["PBXHeadersBuildPhase", "TestAppViewController.h"],
32
+ ["PBXHeadersBuildPhase", "TestApp_Prefix.pch"],
33
+ ["PBXSourcesBuildPhase", "TestAppAppDelegate.m"],
34
+ ["PBXSourcesBuildPhase", "TestAppViewController.m"],
35
+ ["PBXResourcesBuildPhase", "TestAppViewController.xib"],
36
+ ]
37
+ end
38
+
39
+ def file_list_for(target)
40
+ target.all_files.map { |file| [file[:phase]['isa'], file[:object]['path']] }
41
+ end
42
+
43
+ def test_remove_files
44
+ @plugin.retarget! @proj, @regexp, []
45
+ app_file_list, lib_file_list = @proj['targets'].map { |t| file_list_for t }
46
+ assert_equal @golden_list_for_app.sort, app_file_list.sort
47
+ assert_equal [], lib_file_list
48
+ end
49
+
50
+ def test_add_files
51
+ # first remove the files, so they'll be added out of thin air
52
+ @plugin.retarget! @proj, @regexp, []
53
+ @plugin.retarget! @proj, @regexp, ['TestLib']
54
+ app_file_list, lib_file_list = @proj['targets'].map { |t| file_list_for t }
55
+ assert_equal @golden_list_for_app.sort, app_file_list.sort
56
+ assert_equal @golden_list_for_lib, lib_file_list
57
+ end
58
+
59
+ def test_move_files
60
+ @plugin.retarget! @proj, @regexp, ['TestLib']
61
+ app_file_list, lib_file_list = @proj['targets'].map { |t| file_list_for t }
62
+ assert_equal @golden_list_for_app.sort, app_file_list.sort
63
+ assert_equal @golden_list_for_lib, lib_file_list
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ module Plugins; end
2
+
3
+ module Plugins::TestHelper
4
+ # Captures output produced with print.
5
+ def capture_output
6
+ begin
7
+ output = ""
8
+ Kernel.class_eval do
9
+ alias_method :no_print_for_now, :print
10
+ define_method(:print) { |*args| output << args.join }
11
+ end
12
+ yield
13
+ return output
14
+ ensure
15
+ Kernel.class_eval do
16
+ alias_method :print, :no_print_for_now
17
+ undef no_print_for_now
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require 'zerg_xcode'
3
+
4
+ class ShortcutsTest < Test::Unit::TestCase
5
+ def test_load
6
+ proj = ZergXcode.load 'testdata/ZergSupport'
7
+ assert_equal ['ZergSupport', 'ZergTestSupport', 'ZergSupportTests'].sort,
8
+ proj['targets'].map { |target| target['name'] }.sort
9
+ assert_equal 'testdata/ZergSupport.xcodeproj/project.pbxproj',
10
+ proj.source_filename, 'Loading did not set project source'
11
+ end
12
+
13
+ def test_plugin
14
+ ls_instance = ZergXcode.plugin 'ls'
15
+ ls_class = ZergXcode::Plugins::Ls
16
+ assert ls_instance.kind_of?(ls_class), 'plugin retrieves wrong object'
17
+ end
18
+ end