rucola 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/ChangeLog +628 -0
  2. data/History.txt +4 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +106 -0
  5. data/README.txt +126 -0
  6. data/Rakefile +32 -0
  7. data/TODO +28 -0
  8. data/app_generators/rucola/USAGE +6 -0
  9. data/app_generators/rucola/rucola_generator.rb +112 -0
  10. data/app_generators/rucola/templates/Rakefile.erb +12 -0
  11. data/app_generators/rucola/templates/Rakefile.erb.old +156 -0
  12. data/app_generators/rucola/templates/app/controllers/application_controller.rb +22 -0
  13. data/app_generators/rucola/templates/config/Info.plist.erb +28 -0
  14. data/app_generators/rucola/templates/config/boot.rb +2 -0
  15. data/app_generators/rucola/templates/config/environment.rb +11 -0
  16. data/app_generators/rucola/templates/config/environments/debug.rb +3 -0
  17. data/app_generators/rucola/templates/config/environments/release.rb +3 -0
  18. data/app_generators/rucola/templates/config/environments/test.rb +3 -0
  19. data/app_generators/rucola/templates/config/ib_external_class_defs.yml +13 -0
  20. data/app_generators/rucola/templates/misc/English.lproj/InfoPlist.strings.erb +3 -0
  21. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/classes.nib +40 -0
  22. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/info.nib +18 -0
  23. data/app_generators/rucola/templates/misc/English.lproj/MainMenu.nib/keyedobjects.nib +0 -0
  24. data/app_generators/rucola/templates/misc/main.m.erb +15 -0
  25. data/app_generators/rucola/templates/misc/rb_main.rb.erb +13 -0
  26. data/app_generators/rucola/templates/project.pbxproj.erb +299 -0
  27. data/app_generators/rucola/templates/script/plugin +84 -0
  28. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +10 -0
  29. data/app_generators/rucola/templates/test/test_helper.rb +10 -0
  30. data/bin/rucola +12 -0
  31. data/config/hoe.rb +71 -0
  32. data/config/requirements.rb +17 -0
  33. data/lib/rucola.rb +3 -0
  34. data/lib/rucola/info_plist.rb +37 -0
  35. data/lib/rucola/initializer.rb +313 -0
  36. data/lib/rucola/nib.rb +99 -0
  37. data/lib/rucola/rucola_support.rb +9 -0
  38. data/lib/rucola/rucola_support/controllers.rb +2 -0
  39. data/lib/rucola/rucola_support/controllers/rc_controller.rb +7 -0
  40. data/lib/rucola/rucola_support/controllers/rc_window_controller.rb +12 -0
  41. data/lib/rucola/rucola_support/core_ext.rb +2 -0
  42. data/lib/rucola/rucola_support/core_ext/objc.rb +4 -0
  43. data/lib/rucola/rucola_support/core_ext/objc/nsobject.rb +22 -0
  44. data/lib/rucola/rucola_support/core_ext/ruby.rb +4 -0
  45. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +21 -0
  46. data/lib/rucola/rucola_support/initialize_hooks.rb +21 -0
  47. data/lib/rucola/rucola_support/models.rb +1 -0
  48. data/lib/rucola/rucola_support/models/rc_document.rb +10 -0
  49. data/lib/rucola/rucola_support/notifications.rb +1 -0
  50. data/lib/rucola/rucola_support/notifications/notifications.rb +146 -0
  51. data/lib/rucola/rucola_support/rc_app.rb +101 -0
  52. data/lib/rucola/tasks/freeze.rake +44 -0
  53. data/lib/rucola/tasks/interface_builder.rake +80 -0
  54. data/lib/rucola/tasks/main.rake +29 -0
  55. data/lib/rucola/tasks/xcode.rake +43 -0
  56. data/lib/rucola/test_helper.rb +57 -0
  57. data/lib/rucola/version.rb +9 -0
  58. data/lib/rucola/xcode.rb +148 -0
  59. data/log/debug.log +0 -0
  60. data/rucola_generators/controller/USAGE +5 -0
  61. data/rucola_generators/controller/controller_generator.rb +84 -0
  62. data/rucola_generators/controller/templates/controller_template.rb.erb +5 -0
  63. data/rucola_generators/controller/templates/test_controller_template.rb.erb +10 -0
  64. data/rucola_generators/document_model/USAGE +5 -0
  65. data/rucola_generators/document_model/document_model_generator.rb +67 -0
  66. data/rucola_generators/document_model/templates/document_model_template.rb.erb +27 -0
  67. data/rucola_generators/document_model/templates/test_document_model_template.rb.erb +10 -0
  68. data/rucola_generators/window_controller/USAGE +6 -0
  69. data/rucola_generators/window_controller/templates/Window.nib/classes.nib.erb +35 -0
  70. data/rucola_generators/window_controller/templates/Window.nib/info.nib +16 -0
  71. data/rucola_generators/window_controller/templates/Window.nib/keyedobjects.nib +0 -0
  72. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +10 -0
  73. data/rucola_generators/window_controller/templates/window_controller_template.rb.erb +19 -0
  74. data/rucola_generators/window_controller/window_controller_generator.rb +74 -0
  75. data/script/destroy +14 -0
  76. data/script/generate +14 -0
  77. data/script/txt2html +74 -0
  78. data/setup.rb +1585 -0
  79. data/tasks/deployment.rake +27 -0
  80. data/tasks/environment.rake +7 -0
  81. data/tasks/website.rake +17 -0
  82. data/test/fixtures/Info.plist +28 -0
  83. data/test/fixtures/MainMenu.nib/classes.nib +32 -0
  84. data/test/fixtures/MainMenu.nib/info.nib +18 -0
  85. data/test/fixtures/MainMenu.nib/keyedobjects.nib +0 -0
  86. data/test/test_controller_generator.rb +75 -0
  87. data/test/test_core_ext.rb +15 -0
  88. data/test/test_document_model_generator.rb +64 -0
  89. data/test/test_generator_helper.rb +20 -0
  90. data/test/test_helper.rb +13 -0
  91. data/test/test_info_plist.rb +31 -0
  92. data/test/test_nib.rb +73 -0
  93. data/test/test_notifications.rb +75 -0
  94. data/test/test_objc_core_ext.rb +37 -0
  95. data/test/test_rc_app.rb +63 -0
  96. data/test/test_rc_document.rb +18 -0
  97. data/test/test_rc_window_controller.rb +13 -0
  98. data/test/test_rucola.rb +11 -0
  99. data/test/test_rucola_generator.rb +87 -0
  100. data/test/test_window_controller_generator.rb +50 -0
  101. data/test/test_xcode.rb +128 -0
  102. data/website/index.html +199 -0
  103. data/website/index.txt +126 -0
  104. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  105. data/website/stylesheets/screen.css +138 -0
  106. data/website/template.rhtml +48 -0
  107. metadata +189 -0
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ # FIXME: Actually these are not only objc_core_ext tests but also initialize_hooks tests...
4
+
5
+ class FooAfterHook < Rucola::RCController; end
6
+
7
+ describe 'A RCController subclass with Rucola initialize hooks' do
8
+
9
+ it "should register rucola initialization hooks" do
10
+ hook = Proc.new { 'foo' }
11
+ FooAfterHook._rucola_register_initialize_hook(hook)
12
+ hooks = FooAfterHook.instance_variable_get(:@_rucola_initialize_hooks)
13
+ hooks.should.include hook
14
+ end
15
+
16
+ it "should run the hooks after initialization" do
17
+ hook = Proc.new { FooAfterHook.some_class_method }
18
+ FooAfterHook._rucola_register_initialize_hook(hook)
19
+ FooAfterHook.expects(:some_class_method).once
20
+ FooAfterHook.alloc.init
21
+ end
22
+ end
23
+
24
+ class Rucola::RCMockClass < OSX::NSObject; end
25
+ class BarAfterHook < Rucola::RCMockClass; end
26
+
27
+ class NotSubClassOfRC < OSX::NSObject; end
28
+
29
+ describe "NSObject default mixins" do
30
+ it "should automatically mixin the Rucola initialize hooks if it's a subclass of a class that starts with 'Rucola::RC'" do
31
+ BarAfterHook.methods.should.include '_rucola_register_initialize_hook'
32
+ end
33
+
34
+ it "should not mixin the initialize hooks if it's a subclass of a class that starts with anything else but 'Rucola::RC'" do
35
+ NotSubClassOfRC.methods.should.not.include '_rucola_register_initialize_hook'
36
+ end
37
+ end
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require 'pathname'
3
+ include Rucola
4
+
5
+ class FooController; end
6
+ class Person; end
7
+ class PreferencesController; end
8
+
9
+ describe 'Rucola::RCApp' do
10
+ before do
11
+ @root_path = '/some/path/to/root'
12
+ ::RUBYCOCOA_ROOT = Pathname.new(@root_path)
13
+ end
14
+
15
+ it "should return the path to the current root dir" do
16
+ RCApp.root_path.should == @root_path
17
+ end
18
+
19
+ it "should return the path to the current controllers dir" do
20
+ RCApp.controllers_path.should == "#{@root_path}/app/controllers"
21
+ end
22
+
23
+ it "should return the path to the current models dir" do
24
+ RCApp.models_path.should == "#{@root_path}/app/models"
25
+ end
26
+
27
+ it "should return the path to the current views dir" do
28
+ RCApp.views_path.should == "#{@root_path}/app/views"
29
+ end
30
+
31
+ it "should return the path to the current assets dir" do
32
+ RCApp.assets_path.should == "#{@root_path}/app/assets"
33
+ end
34
+
35
+ it "should return the path for a given controller" do
36
+ RCApp.path_for_controller(FooController).should == "#{@root_path}/app/controllers/foo_controller.rb"
37
+ end
38
+
39
+ it "should return the path for a given model" do
40
+ RCApp.path_for_model(Person).should == "#{@root_path}/app/models/person.rb"
41
+ end
42
+
43
+ it "should return the path for a given view" do
44
+ view_path = "#{@root_path}/app/views/Preferences.nib"
45
+ RCApp.path_for_view('Preferences').should == view_path
46
+ RCApp.path_for_view('preferences').should == view_path
47
+ RCApp.path_for_view(PreferencesController).should == view_path
48
+ RCApp.path_for_view(PreferencesController.new).should == view_path
49
+ end
50
+
51
+ it "should return the path for a given asset" do
52
+ asset_path = "#{@root_path}/app/assets/somefile.png"
53
+ RCApp.path_for_asset('somefile.png').should == asset_path
54
+ RCApp.path_for_view('SomeFile.png').should.not == asset_path
55
+ end
56
+
57
+ it "should be included by default in the RCController class" do
58
+ RCController.include?(RCApp).should.be true
59
+ RCController.alloc.init.send(:root_path).should == @root_path
60
+
61
+ RCWindowController.include?(RCApp).should.not.be true
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class SomeDocController < Rucola::RCWindowController; end
4
+ class SomeDoc < Rucola::RCDocument; end
5
+
6
+ describe "RCDocument" do
7
+ it "should initialize a window controller corresponding to itself" do
8
+ # doc = SomeDoc.alloc
9
+ # doc.expects(:addWindowController).with(SomeDocController)
10
+ # doc.init
11
+
12
+ doc = SomeDoc.alloc.init
13
+ controller_mock = mock("SomeDocController mock")
14
+ SomeDocController.expects_alloc_init_returns(controller_mock)
15
+ doc.expects(:addWindowController).with(controller_mock)
16
+ doc.makeWindowControllers
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class FooBarController < Rucola::RCWindowController; end
4
+
5
+ describe 'A subclassed WindowController' do
6
+ it "should know at initialization which nib belongs to it" do
7
+ RUBYCOCOA_ROOT = ''
8
+
9
+ FooBarController.during_init do |obj|
10
+ obj.expects(:initWithWindowNibPath_owner).with('app/views/FooBar.nib', obj).returns(true)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestRucola < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,87 @@
1
+ require File.join(File.dirname(__FILE__), "test_generator_helper.rb")
2
+
3
+ module RubiGen::GeneratorTestHelper
4
+ def assert_generated_symlink(path)
5
+ # For some reason File.exists? doesn't work with symlinks generated with File.symlink(),
6
+ # it does work if the symlink was created with: ln -s
7
+ assert Dir.entries(File.dirname("#{APP_ROOT}/#{path}")).include?(File.basename(path)),"The symbolic link '#{path}' should exist"
8
+ end
9
+ end
10
+
11
+ class TestRucolaGenerator < Test::Unit::TestCase
12
+ include RubiGen::GeneratorTestHelper
13
+
14
+ def setup
15
+ bare_setup
16
+ end
17
+
18
+ def teardown
19
+ bare_teardown
20
+ end
21
+
22
+ # Some generator-related assertions:
23
+ # assert_generated_file(name, &block) # block passed the file contents
24
+ # assert_directory_exists(name)
25
+ # assert_generated_class(name, &block)
26
+ # assert_generated_module(name, &block)
27
+ # assert_generated_test_for(name, &block)
28
+ # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file
29
+ # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet)
30
+ #
31
+ # Other helper methods are:
32
+ # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files)
33
+ # bare_setup - place this in setup method to create the APP_ROOT folder for each test
34
+ # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test
35
+
36
+ def test_generator_without_options
37
+ run_generator('rucola', [APP_ROOT], sources)
38
+
39
+ assert_directory_exists "app/controllers"
40
+ assert_directory_exists "app/models"
41
+ assert_directory_exists "app/views"
42
+ assert_directory_exists "config/environments"
43
+ assert_directory_exists "misc/English.lproj/MainMenu.nib"
44
+ assert_directory_exists "test/controllers"
45
+ assert_directory_exists "test/models"
46
+ assert_directory_exists "vendor"
47
+
48
+ assert_generated_file "Rakefile"
49
+
50
+ assert_generated_file "app/controllers/application_controller.rb"
51
+ assert_generated_file "config/boot.rb"
52
+ assert_generated_file "config/environment.rb"
53
+ assert_generated_file "config/environments/debug.rb"
54
+ assert_generated_file "config/environments/release.rb"
55
+ assert_generated_file "config/environments/test.rb"
56
+ assert_generated_file "config/Info.plist"
57
+ assert_generated_file "config/ib_external_class_defs.yml"
58
+ assert_generated_symlink "Info.plist"
59
+
60
+ assert_generated_file "misc/main.m"
61
+ assert_generated_file "misc/rb_main.rb"
62
+ assert_generated_file "misc/English.lproj/InfoPlist.strings"
63
+ assert_generated_file "misc/English.lproj/MainMenu.nib/classes.nib"
64
+ assert_generated_file "misc/English.lproj/MainMenu.nib/info.nib"
65
+ assert_generated_file "misc/English.lproj/MainMenu.nib/keyedobjects.nib"
66
+
67
+ assert_directory_exists "myproject.xcodeproj"
68
+ assert_generated_file "myproject.xcodeproj/project.pbxproj"
69
+
70
+ assert_generated_file "test/test_helper.rb"
71
+ assert_generated_file "test/controllers/test_application_controller.rb"
72
+
73
+ assert_directory_exists "script"
74
+ assert_generated_file "script/plugin"
75
+ assert `ls -l #{File.expand_path('../tmp/myproject/script/plugin', __FILE__)}`[0..9] == '-rwxr-xr-x'
76
+ end
77
+
78
+ private
79
+ def sources
80
+ [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path))
81
+ ]
82
+ end
83
+
84
+ def generator_path
85
+ "app_generators"
86
+ end
87
+ end
@@ -0,0 +1,50 @@
1
+ require File.join(File.dirname(__FILE__), "test_generator_helper.rb")
2
+
3
+ class TestWindowControllerGenerator < Test::Unit::TestCase
4
+ include RubiGen::GeneratorTestHelper
5
+
6
+ def setup
7
+ bare_setup
8
+ end
9
+
10
+ def teardown
11
+ bare_teardown
12
+ end
13
+
14
+ # Some generator-related assertions:
15
+ # assert_generated_file(name, &block) # block passed the file contents
16
+ # assert_directory_exists(name)
17
+ # assert_generated_class(name, &block)
18
+ # assert_generated_module(name, &block)
19
+ # assert_generated_test_for(name, &block)
20
+ # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file
21
+ # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet)
22
+ #
23
+ # Other helper methods are:
24
+ # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files)
25
+ # bare_setup - place this in setup method to create the APP_ROOT folder for each test
26
+ # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test
27
+
28
+ def test_generator_without_options
29
+ name = "FooBar"
30
+ run_generator('window_controller', [name], sources)
31
+
32
+ assert_generated_file 'app/controllers/foo_bar_controller.rb'
33
+ assert_generated_file 'test/controllers/test_foo_bar_controller.rb'
34
+
35
+ assert_directory_exists 'app/views/FooBar.nib'
36
+ assert_generated_file 'app/views/FooBar.nib/classes.nib'
37
+ assert_generated_file 'app/views/FooBar.nib/info.nib'
38
+ assert_generated_file 'app/views/FooBar.nib/keyedobjects.nib'
39
+ end
40
+
41
+ private
42
+ def sources
43
+ [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path))
44
+ ]
45
+ end
46
+
47
+ def generator_path
48
+ "rucola_generators"
49
+ end
50
+ end
@@ -0,0 +1,128 @@
1
+ require "rubygems"
2
+ require "test/unit"
3
+ require "test/spec"
4
+ require 'mocha'
5
+
6
+ require File.expand_path('../../lib/rucola/xcode', __FILE__)
7
+ include Rucola
8
+
9
+ describe 'Xcode' do
10
+ before do
11
+ @name = 'Baz'
12
+ @project_path = "/foo/bar/#{@name}.xcodeproj"
13
+ @data_path = "#{@project_path}/project.pbxproj"
14
+
15
+ @object_id = '519A79DB0CC8AE6B00CBE85E'.to_ns
16
+ @object_values = { 'isa' => 'PBXNativeTarget', 'name' => @name, 'buildPhases' => [] }.to_ns
17
+ @object = [@object_id, @object_values]
18
+ @data = { 'objects' => { @object_id => @object_values } }.to_ns
19
+ OSX::NSDictionary.stubs(:dictionaryWithContentsOfFile).with(@data_path).returns(@data)
20
+
21
+ @project = Xcode.new(@project_path)
22
+ end
23
+
24
+ it "should initialize" do
25
+ OSX::NSDictionary.expects(:dictionaryWithContentsOfFile).with(@data_path).returns(@data)
26
+
27
+ project = Xcode.new(@project_path)
28
+ project.project_path.to_s.should == @project_path
29
+ project.project.should == @name
30
+ project.project_data.should == @data
31
+ end
32
+
33
+ it "should save the data back as a plist" do
34
+ # atm we don't generate id's, so let's at least make a backup
35
+ backup = "/tmp/#{@name}.xcodeproj.bak"
36
+ File.expects(:exists?).with(backup).returns(true)
37
+ Kernel.expects(:system).with("rm -rf #{backup}")
38
+ Kernel.expects(:system).with("cp -R #{@project_path} #{backup}")
39
+ @project.project_data.expects(:writeToFile_atomically).with(@data_path, true)
40
+ @project.save
41
+ end
42
+
43
+ it "should return an object for a given name" do
44
+ @project.object_for_name('Baz').should == @object
45
+ @project.object_for_name('foo').should.be nil
46
+ end
47
+
48
+ it "should return an object for a given type and name" do
49
+ @project.object_for_type_and_name('PBXNativeTarget', 'Baz').should == @object
50
+ @project.object_for_type_and_name('PBXBuildPhase', 'Baz').should.be nil
51
+ end
52
+
53
+ it "should return an object for the main target" do
54
+ @project.object_for_project_target.should == @object
55
+ end
56
+
57
+ it "should return an object for a given id" do
58
+ @project.object_for_id(@object_id).should == @object
59
+ @project.object_for_id('DOES_NOT_EXIST').should.be nil
60
+ end
61
+
62
+ it "should add an object to the objects" do
63
+ id, values = 'SOME_ID'.to_ns, { 'name' => 'some blah' }.to_ns
64
+ @project.add_object(id, values)
65
+ @project.object_for_id(id).should == [id, values]
66
+ end
67
+
68
+ it "should add a build phase to the project target only once" do
69
+ id, values = 'BUILD_PHASE_ID'.to_ns, { 'name' => 'some blah' }.to_ns
70
+ @project.add_object(id, values)
71
+ @project.add_build_phase_to_project_target(id)
72
+ @project.object_for_project_target.last['buildPhases'].should == [id]
73
+
74
+ @project.add_build_phase_to_project_target(id)
75
+ @project.object_for_project_target.last['buildPhases'].length.should.be 1
76
+ end
77
+
78
+ it "should add an object to a copy build phase" do
79
+ id, values = 'BUILD_PHASE_ID'.to_ns, { 'name' => 'some blah', 'files' => [] }.to_ns
80
+ @project.add_object(id, values)
81
+ @project.add_build_phase_to_project_target(id)
82
+
83
+ @project.add_object_to_build_phase(@object_id, id)
84
+ @project.object_for_id(id).last['files'].should == [@object_id]
85
+ end
86
+
87
+ # it "should create a new framework copy build phase" do
88
+ # # FIXME: until we generate id's this is just a lame test
89
+ # Xcode::NEW_COPY_FRAMEWORKS_BUILD_PHASE = @object
90
+ # @project.new_framework_copy_build_phase.should == @object
91
+ # end
92
+
93
+ it "should change the path of a framework used in the project" do
94
+ id, values = 'FRAMEWORK_ID'.to_ns, { 'name' => 'RubyCocoa.framework', 'path' => '/foo/RubyCocoa.framework', 'sourceTree' => '<absolute>' }.to_ns
95
+ @project.add_object(id, values)
96
+ framework_path = 'vendor/RubyCocoa.framework'
97
+ @project.change_framework_location('RubyCocoa.framework', framework_path)
98
+
99
+ @project.object_for_id(id).last['path'].should == framework_path
100
+ @project.object_for_id(id).last['sourceTree'].should == '<group>'
101
+ end
102
+
103
+ it "should change the path of the RubyCocoa framework" do
104
+ framework_path = 'vendor/RubyCocoa.framework'
105
+ @project.expects(:change_framework_location).with('RubyCocoa.framework', framework_path)
106
+ @project.change_rubycocoa_framework_location(framework_path)
107
+ end
108
+
109
+ it "should bundle a framework with the application" do
110
+ id, values = 'FRAMEWORK_ID'.to_ns, { 'name' => 'BlaBla.framework', 'path' => '/foo/BlaBla.framework', 'sourceTree' => '<absolute>' }.to_ns
111
+ @project.add_object(id, values)
112
+
113
+ @project.bundle_framework('BlaBla.framework')
114
+
115
+ build_phases = @project.object_for_project_target.last['buildPhases']
116
+ build_phases.length.should.be 1
117
+ @project.object_for_id(build_phases.first).last['name'].should == 'Copy Frameworks'
118
+
119
+ build_phase_id = @project.object_for_id(build_phases.first).last['files'].first
120
+ build_phase_id, build_phase = @project.object_for_id(build_phase_id)
121
+ build_phase['fileRef'].should == 'FRAMEWORK_ID'
122
+ end
123
+
124
+ it "should bundle the RubyCocoa framework with the application" do
125
+ @project.expects(:bundle_framework).with('RubyCocoa.framework')
126
+ @project.bundle_rubycocoa_framework
127
+ end
128
+ end
@@ -0,0 +1,199 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7
+ <title>
8
+ rucola
9
+ </title>
10
+ <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11
+ <style>
12
+
13
+ </style>
14
+ <script type="text/javascript">
15
+ window.onload = function() {
16
+ settings = {
17
+ tl: { radius: 10 },
18
+ tr: { radius: 10 },
19
+ bl: { radius: 10 },
20
+ br: { radius: 10 },
21
+ antiAlias: true,
22
+ autoPad: true,
23
+ validTags: ["div"]
24
+ }
25
+ var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
+ versionBox.applyCornersToAll();
27
+ }
28
+ </script>
29
+ </head>
30
+ <body>
31
+ <div id="main">
32
+
33
+ <h1>rucola</h1>
34
+ <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/rucola"; return false'>
35
+ <p>Get Version</p>
36
+ <a href="http://rubyforge.org/projects/rucola" class="numbers">0.0.1</a>
37
+ </div>
38
+ <h1>&#x2192; &#8216;rucola&#8217;</h1>
39
+
40
+
41
+ <h3><span class="caps">SUPER DUPER PRE ALPHA VERSION</span> (expect things to break kinda alpha&#8230;)</h3>
42
+
43
+
44
+ <h2>What</h2>
45
+
46
+
47
+ <p>A Framework for building Cocoa applications in Ruby</p>
48
+
49
+
50
+ <p>Rucola is a light weight framework that helps you write RubyCocoa apps.
51
+ It allows you to build, test, and deploy applications using rake commands,
52
+ eliminating the need to use XCode, however you can use XCode if you wish.</p>
53
+
54
+
55
+ <p>Rucola provides a set of generators to help you generate controllers, window controllers,
56
+ and document-based applications. It also provides APIs for simplifying some of Objective-C&#8217;s
57
+ ways of doing things.</p>
58
+
59
+
60
+ <h2>Installing</h2>
61
+
62
+
63
+ <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">rucola</span></pre></p>
64
+
65
+
66
+ <h2>Demonstration of usage</h2>
67
+
68
+
69
+ <h4>Generating an application skeleton</h4>
70
+
71
+
72
+ <pre><code>rucola MyApp -a "Your Name"</code></pre>
73
+
74
+
75
+ <p>Running this command will give you a complete, working application with a single window already
76
+ bound to your application controller.</p>
77
+
78
+
79
+ <h3>Using Notifications</h3>
80
+
81
+
82
+ <h4>Rucola
83
+ <pre class='syntax'>
84
+ <span class="keyword">class </span><span class="class">Foo</span> <span class="punct">&lt;</span> <span class="constant">Rucola</span><span class="punct">::</span><span class="constant">RCController</span>
85
+ <span class="ident">notify</span> <span class="symbol">:some_method</span><span class="punct">,</span> <span class="symbol">:when</span> <span class="punct">=&gt;</span> <span class="symbol">:something_happens</span>
86
+
87
+ <span class="keyword">def </span><span class="method">some_method</span><span class="punct">(</span><span class="ident">notification</span><span class="punct">)</span>
88
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">w00t!</span><span class="punct">&quot;</span>
89
+ <span class="keyword">end</span>
90
+ <span class="keyword">end</span>
91
+ </pre></h4>
92
+
93
+
94
+ <h4>Objective C (Excluding header file)
95
+ <pre class='syntax'>
96
+ @implementation Foo
97
+ -(id)init {
98
+ if(self = [super init]) {
99
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
100
+ [center addObserver:self selector:(some_method:) name:@&quot;SomethingHappensNotification&quot; object:nil];
101
+ }
102
+ return self;
103
+ }
104
+
105
+ -(void)some_method:(NSNotification *) notification {
106
+ NSLog(&quot;w00t!&quot;);
107
+ }
108
+ @end
109
+ </pre></h4>
110
+
111
+
112
+ <h3>Alternative Way Of Using Notifications</h3>
113
+
114
+
115
+ <pre class='syntax'>
116
+ <span class="keyword">class </span><span class="class">Foo</span> <span class="punct">&lt;</span> <span class="constant">Rucola</span><span class="punct">::</span><span class="constant">RCController</span>
117
+ <span class="ident">notify_on</span> <span class="symbol">:something_happens</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">notification</span><span class="punct">|</span>
118
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">w0t0!</span><span class="punct">&quot;</span>
119
+ <span class="keyword">end</span>
120
+ <span class="keyword">end</span>
121
+ </pre>
122
+
123
+
124
+ <h3>Working with Interface Builder</h3>
125
+
126
+
127
+ <p>A Cocoa application contains `outlets`. Outlets allow you to bind variable names to objects.
128
+ An object can be a user interface element or an instance of a class.</p>
129
+
130
+
131
+ <pre class='syntax'>
132
+ <span class="keyword">class </span><span class="class">ApplicationController</span> <span class="punct">&lt;</span> <span class="constant">Rucola</span><span class="punct">::</span><span class="constant">RCController</span>
133
+ <span class="ident">ib_outlet</span> <span class="symbol">:main_window</span>
134
+
135
+ <span class="keyword">def </span><span class="method">awakeFromNib</span>
136
+ <span class="comment"># All the application delegate methods will be called on this object.</span>
137
+ <span class="constant">OSX</span><span class="punct">::</span><span class="constant">NSApp</span><span class="punct">.</span><span class="ident">delegate</span> <span class="punct">=</span> <span class="constant">self</span>
138
+
139
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">ApplicationController awoke.</span><span class="punct">&quot;</span>
140
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string">Edit: app/controllers/application_controller.rb</span><span class="punct">&quot;</span>
141
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string"><span class="escape">\n</span>It's window is: <span class="expr">#{@main_window.inspect}</span></span><span class="punct">&quot;</span>
142
+ <span class="keyword">end</span>
143
+
144
+ <span class="comment"># NSApplication delegate methods</span>
145
+ <span class="keyword">def </span><span class="method">applicationDidFinishLaunching</span><span class="punct">(</span><span class="ident">notification</span><span class="punct">)</span>
146
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string"><span class="escape">\n</span>Application finished launching.</span><span class="punct">&quot;</span>
147
+ <span class="keyword">end</span>
148
+
149
+ <span class="keyword">def </span><span class="method">applicationWillTerminate</span><span class="punct">(</span><span class="ident">notification</span><span class="punct">)</span>
150
+ <span class="ident">puts</span> <span class="punct">&quot;</span><span class="string"><span class="escape">\n</span>Application will terminate.</span><span class="punct">&quot;</span>
151
+ <span class="keyword">end</span>
152
+ <span class="keyword">end</span>
153
+ </pre>
154
+
155
+
156
+ <p>The `@main_window` variable now points to the user interface window. You can invoke any methods of NSWindow.</p>
157
+
158
+
159
+ <p>There is also a `rake ib:update` that will update your nib files with the outlets you specify in your code.
160
+ For example, if we wanted to add a button to the application controller above, we could add `ib_outlet :my_button`.
161
+ After you&#8217;ve added this, you can run `rake ib:update` and your outlet will be available in interface builder that
162
+ you can now hook up to your UI button.</p>
163
+
164
+
165
+ <h2>Forum</h2>
166
+
167
+
168
+ <p><a href="http://groups.google.com/group/rucola">http://groups.google.com/group/rucola</a></p>
169
+
170
+
171
+ <h2>How to submit patches</h2>
172
+
173
+
174
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
175
+
176
+
177
+ <p>The trunk repository is <code>svn://rubyforge.org/var/svn/rucola/trunk</code> for anonymous access.</p>
178
+
179
+
180
+ <h2>License</h2>
181
+
182
+
183
+ <p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
184
+
185
+
186
+ <h2>Contact</h2>
187
+
188
+
189
+ <p>Comments are welcome. Send an email via the <a href="http://groups.google.com/group/rucola">forum</a></p>
190
+ <p class="coda">
191
+ <a href="http://groups.google.com/group/rucola">Eloy Duran, Justin Palmer</a>, 3rd November 2007<br>
192
+ Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
193
+ </p>
194
+ </div>
195
+
196
+ <!-- insert site tracking codes here, like Google Urchin -->
197
+
198
+ </body>
199
+ </html>