rucola 0.0.3 → 0.5.0

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 (77) hide show
  1. data/ChangeLog +468 -0
  2. data/History.txt +25 -0
  3. data/License.txt +1 -1
  4. data/Manifest.txt +32 -0
  5. data/README.txt +9 -67
  6. data/Rakefile +39 -31
  7. data/TODO +10 -18
  8. data/app_generators/rucola/rucola_generator.rb +15 -8
  9. data/app_generators/rucola/templates/Rakefile.erb +35 -7
  10. data/app_generators/rucola/templates/config/boot.rb +0 -1
  11. data/app_generators/rucola/templates/config/dependencies.rb +31 -0
  12. data/app_generators/rucola/templates/config/environment.rb +0 -1
  13. data/app_generators/rucola/templates/config/environments/debug.rb +13 -1
  14. data/app_generators/rucola/templates/config/environments/release.rb +15 -1
  15. data/app_generators/rucola/templates/config/environments/test.rb +7 -1
  16. data/app_generators/rucola/templates/misc/rb_main.rb.erb +12 -1
  17. data/app_generators/rucola/templates/project.pbxproj.erb +4 -0
  18. data/app_generators/rucola/templates/script/console +10 -0
  19. data/app_generators/rucola/templates/test/controllers/test_application_controller.rb +22 -10
  20. data/app_generators/rucola/templates/test/test_helper.rb +1 -0
  21. data/bin/rucola +4 -2
  22. data/lib/rucola/dependencies.rb +241 -0
  23. data/lib/rucola/dependencies/exclusions.rb +20 -0
  24. data/lib/rucola/dependencies/override_require_and_gem.rb +30 -0
  25. data/lib/rucola/dependencies/resolver.rb +68 -0
  26. data/lib/rucola/fsevents.rb +108 -0
  27. data/lib/rucola/initializer.rb +149 -117
  28. data/lib/rucola/log.rb +61 -0
  29. data/lib/rucola/nib.rb +3 -3
  30. data/lib/rucola/reloader.rb +39 -0
  31. data/lib/rucola/ruby_debug.rb +27 -0
  32. data/lib/rucola/rucola_support.rb +1 -2
  33. data/lib/rucola/rucola_support/core_ext.rb +4 -2
  34. data/lib/rucola/rucola_support/core_ext/objc.rb +9 -4
  35. data/lib/rucola/rucola_support/core_ext/objc/nsimage.rb +22 -0
  36. data/lib/rucola/rucola_support/core_ext/ruby.rb +11 -4
  37. data/lib/rucola/rucola_support/core_ext/ruby/file.rb +11 -0
  38. data/lib/rucola/rucola_support/core_ext/ruby/kernel.rb +16 -0
  39. data/lib/rucola/rucola_support/core_ext/ruby/object.rb +47 -0
  40. data/lib/rucola/rucola_support/core_ext/ruby/string.rb +8 -0
  41. data/lib/rucola/rucola_support/notifications/notifications.rb +26 -28
  42. data/lib/rucola/rucola_support/rc_app.rb +18 -0
  43. data/lib/rucola/tasks/dependencies.rake +49 -0
  44. data/lib/rucola/tasks/deploy.rake +131 -0
  45. data/lib/rucola/tasks/main.rake +39 -6
  46. data/lib/rucola/tasks/xcode.rake +54 -11
  47. data/lib/rucola/test_case.rb +138 -0
  48. data/lib/rucola/test_helper.rb +11 -5
  49. data/lib/rucola/version.rb +2 -2
  50. data/lib/rucola/xcode.rb +39 -9
  51. data/rucola_generators/controller/templates/test_controller_template.rb.erb +19 -7
  52. data/rucola_generators/simple_model/USAGE +5 -0
  53. data/rucola_generators/simple_model/simple_model_generator.rb +54 -0
  54. data/rucola_generators/simple_model/templates/simple_model.rb.erb +2 -0
  55. data/rucola_generators/simple_model/templates/test_simple_model.rb.erb +11 -0
  56. data/rucola_generators/window_controller/templates/test_window_controller_template.rb.erb +24 -13
  57. data/test/fixtures/dependencies/foo.rb +2 -0
  58. data/test/fixtures/dependencies/foo/bar.rb +0 -0
  59. data/test/fixtures/dependencies/foo/baz.rb +0 -0
  60. data/test/fixtures/dependencies/requires_fileutils.rb +1 -0
  61. data/test/fixtures/some_reloadable_class.rb +4 -0
  62. data/test/test_core_ext.rb +80 -0
  63. data/test/test_dependencies.rb +205 -0
  64. data/test/test_fsevents.rb +152 -0
  65. data/test/test_helper.rb +30 -1
  66. data/test/test_initializer.rb +56 -23
  67. data/test/test_log.rb +44 -0
  68. data/test/test_objc_core_ext.rb +23 -0
  69. data/test/test_rc_app.rb +5 -0
  70. data/test/test_reloader.rb +28 -0
  71. data/test/test_rucola_generator.rb +7 -0
  72. data/test/test_simple_model_generator.rb +48 -0
  73. data/test/test_xcode.rb +85 -5
  74. data/website/index.html +17 -91
  75. data/website/index.txt +14 -81
  76. data/website/template.rhtml +1 -1
  77. metadata +120 -76
@@ -0,0 +1,131 @@
1
+ require 'uri'
2
+
3
+ namespace :deploy do
4
+ DEPLOY_NAME = "#{APPNAME}_#{APPVERSION}"
5
+ PKG = File.join('pkg', "#{DEPLOY_NAME}.dmg")
6
+
7
+ directory 'pkg'
8
+
9
+ desc "Package the application as a disk image"
10
+ task :package => :pkg do
11
+ FileUtils.rm(PKG) if File.exist?(PKG)
12
+ puts 'Creating Image...'
13
+ sh "hdiutil create -volname '#{DEPLOY_NAME}' -srcfolder 'build/Release/#{TARGET}' '#{PKG}'"
14
+ puts ''
15
+ end
16
+
17
+ desc "Write a new appcast rss file"
18
+ task :sparkle_appcast => :pkg do
19
+ check_if_sparkle_info_exists!
20
+
21
+ puts "Creating appcast..."
22
+ appcast_filename = File.basename(INFO_PLIST['SUFeedURL'])
23
+
24
+ appcast = %{
25
+ <?xml version="1.0" encoding="utf-8"?>
26
+ <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
27
+ <channel>
28
+ <title>#{APPNAME} Changelog</title>
29
+ <link>#{INFO_PLIST['SUFeedURL']}</link>
30
+ <description>#{INFO_PLIST['SUAppDescription']}</description>
31
+ <language>en</language>
32
+ <item>
33
+ <title>#{APPNAME} - #{APPVERSION}</title>
34
+ <description>#{INFO_PLIST['SUPublicReleaseNotesURL']}#{DEPLOY_NAME}_release_notes.html</description>
35
+ <pubDate>#{Time.now}</pubDate>
36
+ <enclosure url="#{INFO_PLIST['SUPublicReleaseURL']}#{DEPLOY_NAME}.dmg" length="#{File.size(PKG)}" type="application/octet-stream"/>
37
+ </item>
38
+ </channel>
39
+ </rss>}.sub(/^\n/, '')
40
+
41
+ File.open("pkg/#{appcast_filename}", 'w') { |f| f.write appcast }
42
+ puts "created: pkg/#{appcast_filename}\n\n"
43
+ end
44
+
45
+ desc "Write a new release notes html file. Looks for ReleaseNotes/#{DEPLOY_NAME}"
46
+ task :release_notes => :pkg do
47
+ begin
48
+ require 'RedCloth'
49
+ rescue LoadError
50
+ puts "Unable write the release notes html, because the RedCloth gem was not found."
51
+ exit
52
+ end
53
+
54
+ puts "Creating release notes..."
55
+
56
+ changelog = File.join(SOURCE_ROOT, 'ReleaseNotes', DEPLOY_NAME)
57
+ body = RedCloth.new(File.read(changelog))
58
+ html = %{
59
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
60
+ <html>
61
+ <body>
62
+ #{body.to_html}
63
+ </body>
64
+ </html>
65
+ }.sub(/^\n/, '').gsub(/\t/, ' ').gsub(/\n+/, "\n")
66
+
67
+ File.open("pkg/#{DEPLOY_NAME}_release_notes.html", 'w') { |f| f.write html }
68
+ puts "created: pkg/#{DEPLOY_NAME}_release_notes.html\n\n"
69
+ end
70
+
71
+ desc 'Removes the pkg/ directory.'
72
+ task :clean do
73
+ build_dir = 'pkg/'
74
+ if File.exist? build_dir
75
+ puts "Removing #{build_dir}"
76
+ FileUtils.rm_rf build_dir
77
+ end
78
+ end
79
+
80
+ desc "Upload pkg/ files. Specify the uri's with the constants PUBLISH_URI & APPCAST_URI."
81
+ task :upload do
82
+ if File.exist? PKG
83
+ puts "\nUploading: #{PKG}"
84
+ do_upload(PUBLISH_URI, PKG)
85
+ puts "\n\n"
86
+ end
87
+
88
+ appcast_path = "pkg/#{File.basename(INFO_PLIST['SUFeedURL'])}" if INFO_PLIST['SUFeedURL']
89
+ if appcast_path and File.exist?(appcast_path)
90
+ puts "\nUploading: #{appcast_path}"
91
+ do_upload(APPCAST_URI, appcast_path)
92
+ puts "\n\n"
93
+ end
94
+
95
+ release_notes_path = "pkg/#{DEPLOY_NAME}_release_notes.html"
96
+ if File.exist? release_notes_path
97
+ puts "\nUploading: #{release_notes_path}"
98
+ do_upload(APPCAST_URI, release_notes_path)
99
+ puts "\n\n"
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def check_if_sparkle_info_exists!
106
+ [
107
+ ['SUFeedURL', 'http://mydomain.com/my_app/appcast.xml'],
108
+ ['SUAppDescription', 'My terrific application!'],
109
+ ['SUPublicReleaseNotesURL', 'http://mydomain.com/my_app/', "Don't forget the last '/' which specifies that it's a directory.\nThe constructed url would look like: http://mydomain.com/my_app/my_app_1.1_release_notes.html"],
110
+ ['SUPublicReleaseURL', 'http://mydomain.com/files/my_app/', "Don't forget the last '/' which specifies that it's a directory.\nThe constructed url would look like: http://mydomain.com/files/my_app/my_app_1.1.dmg"],
111
+ ].each { |x| check_sparkle_for_key(*x) }
112
+ end
113
+
114
+ def check_sparkle_for_key(key, example_value, notes = nil)
115
+ if INFO_PLIST[key].nil?
116
+ puts "In order to create a sparkle appcast, you need to specify the value for '#{key}' in the Info.plist file."
117
+ puts "Eg:\n\n <key>#{key}</key>\n <string>#{example_value}</string>"
118
+ puts "\nNote:\n#{notes}" if notes
119
+ exit
120
+ end
121
+ end
122
+
123
+ # calls the upload method based on the scheme
124
+ def do_upload(uri, file)
125
+ send(uri.scheme, uri, file, File.basename(file))
126
+ end
127
+
128
+ def scp(uri, file, dest_file)
129
+ sh "scp -P #{ uri.port || '22' } #{file} #{uri.userinfo}@#{uri.host}:#{uri.path}/#{dest_file}"
130
+ end
131
+ end
@@ -6,12 +6,39 @@ require 'rucola/nib'
6
6
  require 'rucola/rucola_support'
7
7
 
8
8
  # set the env, default to debug if we are running a rake task.
9
- ENV['RUBYCOCOA_ENV'] ||= 'debug'
10
- ENV['RUBYCOCOA_ROOT'] ||= SOURCE_ROOT
9
+ if ARGV[0] && %w{ release deploy }.include?(ARGV[0])
10
+ mode = 'release'
11
+ else
12
+ ENV['RUBYCOCOA_ENV'] ||= 'debug'
13
+ ENV['RUBYCOCOA_ROOT'] ||= SOURCE_ROOT
14
+
15
+ mode = ENV['RUBYCOCOA_ENV']
16
+ end
17
+ puts "Running in mode: #{mode}\n\n"
11
18
 
12
- require 'rucola/initializer'
19
+ # Load the applications Info.plist file
20
+ INFO_PLIST = OSX::NSDictionary.dictionaryWithContentsOfFile(File.join(SOURCE_ROOT, 'Info.plist'))
13
21
 
14
- puts "RUNNING IN MODE: #{RUBYCOCOA_ENV.upcase}\n\n"
22
+ # Set some application defaults for the rake tasks
23
+ APPNAME = INFO_PLIST['CFBundleExecutable']
24
+ APPVERSION = INFO_PLIST['CFBundleVersion']
25
+ TARGET = "#{APPNAME}.app"
26
+
27
+ # Now that the env is set let initializer do it's work
28
+ require 'rucola/initializer'
29
+ # Load the configuration
30
+ module Rucola
31
+ class Initializer
32
+ class << self
33
+ def run
34
+ yield instance.configuration
35
+ end
36
+ end
37
+ end
38
+ end
39
+ CONFIGURATION = Rucola::Configuration.new
40
+ Rucola::Initializer.instance.instance_variable_set(:@configuration, CONFIGURATION)
41
+ CONFIGURATION.load_environment_configuration!
15
42
 
16
43
  # FIXME: We also need to check if the user uses a frozen rc framework
17
44
  RUBYCOCOA_FRAMEWORK = OSX::NSBundle.bundleWithIdentifier('com.apple.rubycocoa').bundlePath.to_s
@@ -20,14 +47,20 @@ RUBYCOCOA_FRAMEWORK = OSX::NSBundle.bundleWithIdentifier('com.apple.rubycocoa').
20
47
 
21
48
  # Get all the tasks
22
49
  Dir["#{File.dirname(__FILE__)}/*.rake"].each {|file| load file unless ['main.rake'].include? File.basename(file) }
23
- Dir[(ENV['RUBYCOCOA_ROOT'] + '/vendor/plugins/*/tasks/*.rake').to_s].each { |r| load r }
50
+ Dir[(SOURCE_ROOT + '/vendor/plugins/*/tasks/*.rake').to_s].each { |r| load r }
51
+
24
52
  task :default => 'xcode:build'
25
53
 
26
54
  desc 'Runs all the clean tasks'
27
- task :clean => 'xcode:clean'
55
+ task :clean => ['xcode:clean', 'dependencies:clean', 'deploy:clean']
28
56
 
29
57
  Rake::TestTask.new do |t|
30
58
  t.test_files = FileList['test/*/test_*.rb']
31
59
  t.options = '-rr'
32
60
  t.verbose = true
33
61
  end
62
+
63
+ desc 'Update any missing/changed files, if you updated from an earlier version of Rucola.1'
64
+ task :update do
65
+ sh "cd .. && rucola #{File.basename(SOURCE_ROOT)}"
66
+ end
@@ -1,3 +1,10 @@
1
+ desc "Shortcut for doing a release build"
2
+ task :release do
3
+ RUBYCOCOA_ENV = 'release'
4
+ Rake::Task['xcode:build'].invoke
5
+ end
6
+
7
+ # we should probably rename this namespace and task to 'build'
1
8
  namespace :xcode do
2
9
 
3
10
  def config
@@ -8,27 +15,36 @@ namespace :xcode do
8
15
  # get the users build dir
9
16
  prefs = OSX::NSUserDefaults.standardUserDefaults
10
17
  prefs.addSuiteNamed 'com.apple.xcode'
11
- prefs['PBXApplicationwideBuildSettings']['SYMROOT'] || './build'
18
+ # first check if there are any xcode prefs at all.
19
+ if prefs['PBXApplicationwideBuildSettings']
20
+ prefs['PBXApplicationwideBuildSettings']['SYMROOT'] || './build'
21
+ else
22
+ './build'
23
+ end
12
24
  end
13
25
 
14
26
  def build_root
15
27
  File.expand_path("#{build_dir}/#{config}/#{TARGET}")
16
28
  end
17
29
 
30
+ def executable
31
+ "#{build_root}/Contents/MacOS/#{APPNAME}"
32
+ end
33
+
18
34
  desc 'Builds the application'
19
35
  task :build do
20
- executable = "#{build_root}/Contents/MacOS/#{APPNAME}"
36
+ # First check if we're in release and need to bundle anything
37
+ Rake::Task['dependencies:copy'].invoke if RUBYCOCOA_ENV == 'release'
21
38
 
22
39
  # For now let's do xcodebuild everytime.
23
40
  # Otherwise nibs that are updated will not be updated in the bundle...
24
41
  sh "xcodebuild -configuration #{config}"
25
42
 
26
- # unless File.exists?(executable)
27
- # sh "xcodebuild -configuration #{config}"
28
- # else
29
- # puts "Build already exists, skipping. (Use clean if you really really want a new build.)\n\n"
30
- # end
31
-
43
+ Rake::Task['xcode:run'].invoke unless ENV['DONT_START_RUBYCOCOA_APP']
44
+ end
45
+
46
+ desc 'Run a build'
47
+ task :run do
32
48
  # Make sure the app is brought to the front once launched.
33
49
  Thread.new(executable) do |executable|
34
50
  sleep 0.025 until OSX::NSWorkspace.sharedWorkspace.launchedApplications.any? {|dict| dict['NSApplicationName'] == APPNAME }
@@ -36,12 +52,39 @@ namespace :xcode do
36
52
  end
37
53
 
38
54
  # launch app with the correct env set
39
- sh "RUBYCOCOA_ENV='#{RUBYCOCOA_ENV}' RUBYCOCOA_ROOT='#{RUBYCOCOA_ROOT}' #{executable}"
55
+ if RUBYCOCOA_ENV == 'release'
56
+ sh executable
57
+ else
58
+ sh "RUBYCOCOA_ENV='#{RUBYCOCOA_ENV}' RUBYCOCOA_ROOT='#{RUBYCOCOA_ROOT}' #{executable}"
59
+ end
40
60
  end
41
61
 
42
62
  desc 'Removes the build'
43
63
  task :clean do
44
- puts "Removing #{build_root}"
45
- FileUtils.rm_rf build_root
64
+ if File.exist? build_dir
65
+ puts "Removing #{build_dir}"
66
+ FileUtils.rm_rf build_dir
67
+ end
68
+ end
69
+
70
+ namespace :frameworks do
71
+ desc "Add any framework in vendor/frameworks which isn't in the project yet to the project and bundle it"
72
+ task :update do
73
+ if File.exist? 'vendor/frameworks'
74
+ project = Rucola::Xcode.new File.join(SOURCE_ROOT, "#{APPNAME}.xcodeproj")
75
+ framework_names = project.frameworks.map { |f| f.last['name'] }
76
+ changes = false
77
+ FileList['vendor/frameworks/*.framework'].each do |framework|
78
+ framework_name = File.basename(framework)
79
+ unless framework_names.include?(framework_name)
80
+ changes = true
81
+ puts "Adding #{framework_name} to project."
82
+ project.add_framework(framework_name, framework)
83
+ project.bundle_framework(framework_name)
84
+ end
85
+ end
86
+ project.save if changes
87
+ end
88
+ end
46
89
  end
47
90
  end
@@ -0,0 +1,138 @@
1
+ class OSX::NSObject
2
+ class << self
3
+ # An array of defined ib_outlets.
4
+ #
5
+ # Only used in test cases.
6
+ def defined_ib_outlets
7
+ @defined_ib_outlets ||= []
8
+ end
9
+
10
+ # Override ib_outlets so we can store which ones need to be defined.
11
+ #
12
+ # Only used in test cases.
13
+ def ib_outlets(*outlets)
14
+ defined_ib_outlets.concat(outlets.flatten)
15
+ end
16
+ alias_method :ib_outlet, :ib_outlets
17
+ end
18
+ end
19
+
20
+ module Rucola
21
+ module TestCase
22
+ # Defines the controller that will be tested.
23
+ #
24
+ # class ApplicationController < OSX::NSObject
25
+ # ib_outlet :window
26
+ # ib_outlets :tableView, :searchField
27
+ # ib_outlets :textField
28
+ # end
29
+ #
30
+ # class TestFoo < Test::Unit::TestCase
31
+ # tests ApplicationController
32
+ #
33
+ # def after_setup
34
+ # ib_outlets :window => mock("Main Window"),
35
+ # :tableView => OSX::NSTableView.alloc.init,
36
+ # :searchField => OSX::NSSearchField.alloc.init
37
+ #
38
+ # window.stubs(:title => 'Main Window')
39
+ # tableView.addTableColumn OSX::NSTableColumn.alloc.init
40
+ # searchField.stringValue = "foo"
41
+ # end
42
+ #
43
+ # def test_something
44
+ # p controller # => #<ApplicationController:0xdfa1ce class='ApplicationController' id=0x1e8d0e0>
45
+ # p window.title # => "Main Window"
46
+ # p tableView.tableColumns # => #<NSCFArray [#<OSX::NSTableColumn:0xdf9d0a class='NSTableColumn' id=0x1e90d00>]>
47
+ # p searchField # => #<OSX::NSSearchField:0xdfa43a class='NSSearchField' id=0x1e84cb0>
48
+ #
49
+ # # Note that we haven't set the textField ib_outlet to anything else in the after_setup method,
50
+ # # so it will be a stub which responds to everything by returning nil.
51
+ # p textField # => #<Mock:textField>
52
+ # end
53
+ # end
54
+ def tests(class_to_be_tested)
55
+ @class_to_be_tested = class_to_be_tested
56
+ include Rucola::TestCase::InstanceMethods
57
+ end
58
+
59
+ module InstanceMethods
60
+ # Sets up the ib_outlets to all be stubs which respond to everything with nil.
61
+ #
62
+ # In your test use #after_setup to do any custom setup.
63
+ def setup
64
+ class_to_be_tested.defined_ib_outlets.each do |outlet|
65
+ ib_outlet(outlet, stub_everything(outlet.to_s))
66
+ end
67
+ after_setup if respond_to? :after_setup
68
+ end
69
+
70
+ # Sets the ib_outlets and instance to be tested to nil at the end of the test.
71
+ #
72
+ # In your test use #after_teardown to do any custom teardown.
73
+ def teardown
74
+ class_to_be_tested.defined_ib_outlets.each do |outlet|
75
+ instance_to_be_tested.instance_variable_set("@#{outlet}", nil)
76
+ end
77
+ @instance_to_be_tested = nil
78
+ after_teardown if respond_to? :after_teardown
79
+ end
80
+
81
+ # Returns the class that's to be tested.
82
+ def class_to_be_tested
83
+ self.class.instance_variable_get(:@class_to_be_tested)
84
+ end
85
+
86
+ # An instance of the class that's to be tested.
87
+ def instance_to_be_tested
88
+ @instance_to_be_tested ||= class_to_be_tested.alloc.init
89
+ end
90
+ alias_method :controller, :instance_to_be_tested
91
+
92
+ # Lets you get an instance variable from the instance.
93
+ #
94
+ # obj.instance_variable_set(:@some_attr, 'foo')
95
+ # assigns(:some_attr) # => 'foo'
96
+ #
97
+ # You can also set an instance variable in the instance.
98
+ #
99
+ # obj.assigns(:some_attr, 'bar')
100
+ # obj.instance_variable_get(:@some_attr) # => 'bar'
101
+ def assigns(name, obj = nil)
102
+ obj.nil? ? instance_to_be_tested.instance_variable_get("@#{name}") : instance_to_be_tested.instance_variable_set("@#{name}", obj)
103
+ end
104
+
105
+ # Defines instance variables in the instance which represent the ib_outlets.
106
+ # It basically just sets the instance variables, but also creates shorcut accessors to get at them from your tests.
107
+ #
108
+ # def after_setup
109
+ # ib_outlet :textField, OSX::NSTextField.alloc.init
110
+ # p textField # => #<OSX::NSTextField:0xdfa3f4 class='NSTextField' id=0x1e842b0>
111
+ # end
112
+ #
113
+ # Note that not every class can be instantiated in a test.
114
+ # So you can also supply something like a mock.
115
+ def ib_outlet(name, obj)
116
+ unless respond_to? name
117
+ self.class.class_eval do
118
+ define_method(name) { assigns(name) }
119
+ private name
120
+ end
121
+ end
122
+ assigns(name, obj)
123
+ end
124
+
125
+ # Shortcut method to defined multiple ib_outlets by supplying a hash.
126
+ #
127
+ # def after_setup
128
+ # ib_outlets :window => mock("Main Window"),
129
+ # :tableView => OSX::NSTableView.alloc.init,
130
+ # :searchField => OSX::NSSearchField.alloc.init
131
+ # end
132
+ def ib_outlets(outlets)
133
+ outlets.each {|k,v| ib_outlet(k, v) }
134
+ end
135
+ end
136
+ end
137
+ end
138
+ Test::Unit::TestCase.send(:extend, Rucola::TestCase)
@@ -9,12 +9,10 @@ class Object
9
9
  end
10
10
  end
11
11
 
12
- module OSX
12
+ module OSX #:nodoc:
13
13
  # Allows methods to be overriden with a different arity.
14
14
  #
15
- # TODO: Check with Laurent if this is bad?
16
- # Otherwise we should maybe override the stub method to set this to true
17
- # when the object is a subclass of OSX::NSObject and set it to false again after the stubbing.
15
+ # FIXME: This seems to destroy the #super_init etc from working
18
16
  def self._ignore_ns_override; true; end
19
17
 
20
18
  class NSObject
@@ -68,4 +66,12 @@ module OSX
68
66
  res
69
67
  end
70
68
  end
71
- end
69
+ end
70
+
71
+ # Sets the RUBYCOCOA_ENV for the duration of the block.
72
+ def with_env(env)
73
+ before = Rucola::RCApp.env
74
+ Rucola::RCApp.stubs(:env).returns(env)
75
+ yield
76
+ Rucola::RCApp.stubs(:env).returns(before)
77
+ end