hotcocoa 0.6.0pre → 0.6.0pre2

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,27 +1,27 @@
1
1
  # hotcocoa
2
2
 
3
3
  * [http://github.com/ferrous26/hotcocoa](http://github.com/ferrous26/hotcocoa)
4
- * [Documentation](http://rdoc.info/github/ferrous26/hotcocoa/master/frames) WIP
4
+ * [Documentation](http://rdoc.info/github/ferrous26/hotcocoa/master/frames)
5
5
 
6
6
  ## Description
7
7
 
8
8
  HotCocoa is a thin, idiomatic Ruby layer that sits above Cocoa and
9
- other frameworks. HotCocoa used to be included in MacRuby but is now
10
- managed as a separate gem. This will allow HotCocoa to accept
11
- contributions and evolve more quickly. To see more information on
12
- HotCocoa (including tutorial) see
9
+ other frameworks. The goal of the project is to simplify the process of creating
10
+ and configuring Cocoa objects used when building native Mac apps. To get more
11
+ information on HotCocoa (including tutorials) see
13
12
  [http://macruby.org](http://macruby.org).
14
13
 
15
14
  ## Note
16
15
 
17
- This is a fork of HotCocoa that is being kept alive by myself and
18
- other contributors; most of the work now is going in to documentation
19
- and regression tests, but we are still adding new mappings, improving
20
- existing mappings, and adding other features that we feel help meet
21
- the goals of this project.
16
+ HotCocoa has ambitious goals that are difficult to accomplish with the input of
17
+ only a few people. Feedback is the easiest way to contribute and goes a long way
18
+ to making sure HotCocoa is on the right path to accomplishing those goals.
22
19
 
23
- If you find issues with HotCocoa you can open issues and I (or
24
- another contributor) will try to fix them.
20
+ There are still some APIs that need documentation, regression tests that need to
21
+ be written, and tutorials to be updated; but new features and improved performance
22
+ will also be coming in the not too distant future. If you find issues with
23
+ HotCocoa, don't hesitate to open tickets on Github (or try to fix it yourself and
24
+ send in the patch :)).
25
25
 
26
26
  There are a list of
27
27
  [gotchas](https://github.com/ferrous26/hotcocoa/wiki/Gotchas) in the
@@ -29,22 +29,33 @@ wiki.
29
29
 
30
30
  ## Install
31
31
 
32
- * sudo macrake install
32
+ From rubygems:
33
33
 
34
- This fork is only available from source right now.
34
+ sudo macgem install hotcocoa --pre
35
35
 
36
- Note: If you are on Snow Leopard, you will also need the
36
+ You need to add the `--pre` flag since HotCocoa 0.6 is not officially released yet.
37
+ Or you can clone the repository on Github and install from there:
38
+
39
+ git clone git://github.com/ferrous26/hotcocoa
40
+ cd hotcocoa
41
+ sudo macrake install
42
+
43
+ __Note__: If you are on Snow Leopard, you will also need the
37
44
  [Bridge Support Preview](http://www.macruby.org/files/BridgeSupport%20Preview%203.zip)
38
- in order to run this fork of HotCocoa. Read about it on the
45
+ in order to run HotCocoa. Read about it on the
39
46
  [MacRuby Blog](http://www.macruby.org/blog/2010/10/08/bridgesupport-preview.html).
40
47
 
48
+ __Note 2__: You will also need the Mac OS X developer tools in order
49
+ to build apps. Xcode is not required, but the compiler toolchain is
50
+ needed.
51
+
41
52
  ## Documentation
42
53
 
43
54
  Documentation is a work in progress; some of the documentation is
44
- being ported from the MacRuby website where it is still available.
55
+ being ported from the MacRuby website and you can still view it there.
45
56
 
46
- The documentation does not include the mappings right now due to the
47
- way that mappings are implemented; a YARD plug-in is needed for that.
57
+ The documentation currently does not include the mappings right now due to the
58
+ way that mappings are implemented; a YARD plug-in will be needed for thatv
48
59
 
49
60
  ## Contributing to HotCocoa
50
61
 
@@ -9,6 +9,9 @@ module Application
9
9
  # This class is responsible for building application bundles, but could
10
10
  # theoretically be used to build other bundles, such as frameworks, with
11
11
  # only a few changes.
12
+ #
13
+ # It is designed to work in conjunction with an {Application::Specification}
14
+ # object which would provide details on how to build the bundle.
12
15
  class Builder
13
16
 
14
17
  ##
@@ -22,17 +25,20 @@ module Application
22
25
  new(spec).build(opts)
23
26
  end
24
27
 
28
+ ##
29
+ # Cached spec.
30
+ #
25
31
  # @return [Application::Specification]
26
32
  attr_reader :spec
27
33
 
28
34
  # @param [Application::Specification]
29
35
  def initialize spec
30
36
  @spec = case spec
31
- when Specification
32
- spec
33
- when String
34
- Specification.load spec
35
- end
37
+ when Specification
38
+ spec
39
+ when String
40
+ Specification.load spec
41
+ end
36
42
  end
37
43
 
38
44
  # @param [Hash]
@@ -50,10 +56,15 @@ module Application
50
56
  deploy if opts[:deploy]
51
57
  end
52
58
 
59
+ ##
60
+ # Run the bundle's binary directly so `STDOUT` and `STDERR` appear in the
61
+ # terminal.
53
62
  def run
54
63
  `"./#{executable_file}"`
55
64
  end
56
65
 
66
+ ##
67
+ # Destroy the existing bundle, if it exists.
57
68
  def remove_bundle_root
58
69
  FileUtils.rm_rf bundle_root if File.exist?(bundle_root)
59
70
  end
@@ -62,26 +73,37 @@ module Application
62
73
  private
63
74
 
64
75
  ##
65
- # Build arguments list and call to `macruby_deploy`.
76
+ # Call `macruby_deploy` to lend a helping hand.
66
77
  def deploy
67
78
  puts `macruby_deploy --embed --gem hotcocoa #{deploy_options} #{bundle_root}`
68
79
  end
69
80
 
81
+ ##
82
+ # Build the options list to pass to `macruby_deploy`.
70
83
  def deploy_options
71
84
  options = []
72
85
  spec.gems.each { |g| options << "--gem #{g}" }
73
86
  options << '--bs' if spec.embed_bs?
74
87
  options << '--compile' if spec.compile?
75
- options << '--no-stdlib' unless spec.stdlib # @todo use attribute properly
88
+ options << '--no-stdlib' unless spec.stdlib
89
+ if spec.stdlib.respond_to? :each
90
+ spec.stdlib.each do |lib|
91
+ options << "--stdlib #{lib}"
92
+ end
93
+ end
76
94
  options.join(' ')
77
95
  end
78
96
 
97
+ ##
98
+ # Setup the basic directory structure of a bundle.
79
99
  def build_bundle_structure
80
100
  [bundle_root, contents_root, frameworks_root, macos_root, resources_root].each do |dir|
81
101
  Dir.mkdir(dir) unless File.exist?(dir)
82
102
  end
83
103
  end
84
104
 
105
+ ##
106
+ # Setup the remaining standard files for the bundle.
85
107
  def write_bundle_files
86
108
  write_pkg_info_file
87
109
  write_info_plist_file
@@ -89,6 +111,8 @@ module Application
89
111
  write_ruby_main
90
112
  end
91
113
 
114
+ ##
115
+ # Copy the sources, usually just the ruby source code, into the bundle.
92
116
  def copy_sources
93
117
  spec.sources.each do |source|
94
118
  destination = File.join(resources_root, source)
@@ -97,6 +121,12 @@ module Application
97
121
  end
98
122
  end
99
123
 
124
+ ##
125
+ # @todo An example project that uses a `xib`.
126
+ #
127
+ # Copy the resources, such as images and data, into the bundle.
128
+ # Resources can also include interface builder files, which will
129
+ # be compiled for you.
100
130
  def copy_resources
101
131
  spec.resources.each do |resource|
102
132
  destination = File.join(resources_root, resource.split('/')[1..-1].join('/'))
@@ -111,21 +141,36 @@ module Application
111
141
  end
112
142
  end
113
143
 
144
+ ##
145
+ # Compile any CoreData model files and copy them to the bundle.
114
146
  def compile_data_models
115
147
  spec.data_models.each do |data|
116
148
  `/Developer/usr/bin/momc #{data} #{resources_root}/#{File.basename(data, ".xcdatamodel")}.mom`
117
149
  end
118
150
  end
119
151
 
152
+ ##
153
+ # Copy the icon file to the bundle.
120
154
  def copy_icon_file
121
155
  FileUtils.cp spec.icon, icon_file
122
156
  end
123
157
 
158
+ ##
159
+ # Generate the `PkgInfo` file for the bundle. Every bundle needs this
160
+ # in order identify its type of bundle and signature.
124
161
  def write_pkg_info_file
125
- File.open(pkg_info_file, 'wb') { |f| f.write "#{spec.type}#{spec.signature}" }
162
+ File.open(pkg_info_file, 'wb') do |file|
163
+ file.write "#{spec.type}#{spec.signature}"
164
+ end
126
165
  end
127
166
 
128
- def write_info_plist_file
167
+ ##
168
+ # @todo Development region needs to be configurable in the future. And
169
+ # so should the default class. They should still both have defaults.
170
+ #
171
+ # Generate and the `Info.plist` for the bundle using fields from the
172
+ # cached app spec.
173
+ def info_plist
129
174
  # http://developer.apple.com/library/mac/#documentation/General/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html%23//apple_ref/doc/uid/TP40009254-SW1
130
175
  info = {
131
176
  CFBundleName: spec.name,
@@ -138,14 +183,28 @@ module Application
138
183
  CFBundleInfoDictionaryVersion: '6.0',
139
184
  NSPrincipalClass: 'NSApplication',
140
185
  LSUIElement: spec.agent,
141
- LSMinimumSystemVersion: '10.6.7', # should match MacRuby
186
+ LSMinimumSystemVersion: '10.6.7', # @todo should match MacRuby
142
187
  }
143
188
  info[:CFBundleIconFile] = File.basename(spec.icon) if spec.icon_exists?
189
+ info.merge! spec.plist # should always be done last
190
+ info.to_plist
191
+ end
144
192
 
145
- File.open(info_plist_file, 'w') { |f| f.write info.to_plist }
193
+ ##
194
+ # Wirte out the generated info plist for the bundle.
195
+ def write_info_plist_file
196
+ File.open(info_plist_file, 'w') do |file|
197
+ file.write info_plist
198
+ end
146
199
  end
147
200
 
148
- # @todo something better than puts `gcc`
201
+ ##
202
+ # @todo Need a better way of specifying the supported architectures,
203
+ # hard coding makes HotCocoa susceptible to the same problem
204
+ # as before.
205
+ #
206
+ # Create the standard bootstrap binary to launch a MacRuby app and place
207
+ # it in the bundle.
149
208
  def build_executable
150
209
  File.open(objective_c_source_file, 'wb') do |f|
151
210
  f.write %{
@@ -158,12 +217,14 @@ module Application
158
217
  }
159
218
  end
160
219
  Dir.chdir(macos_root) do
161
- puts `gcc main.m -o #{executable_file_name} -arch x86_64 -framework MacRuby -framework Foundation -fobjc-gc-only`
220
+ puts `#{RbConfig::CONFIG['CC']} main.m -o #{executable_file_name} -arch x86_64 -framework MacRuby -framework Foundation -fobjc-gc-only`
162
221
  end
163
222
  File.unlink(objective_c_source_file)
164
223
  end
165
224
 
166
- # Borrow rb_main from MacRuby Xcode templates
225
+ ##
226
+ # Borrow `rb_main` from MacRuby Xcode templates and use it to load all
227
+ # the sources in the bundle at boot time.
167
228
  def write_ruby_main
168
229
  File.open(main_ruby_source_file, 'wb') do |f|
169
230
  f.write <<-EOF
@@ -186,50 +247,75 @@ module Application
186
247
  end
187
248
  end
188
249
 
250
+ ##
251
+ # Path where to put the bundle.
189
252
  def bundle_root
190
253
  "#{spec.name}.app"
191
254
  end
192
255
 
256
+ ##
257
+ # Path where to put the `Contents' directory of the bundle.
193
258
  def contents_root
194
259
  File.join(bundle_root, 'Contents')
195
260
  end
196
261
 
262
+ ##
263
+ # Path where to put the `Frameworks' directory of the bundle.
197
264
  def frameworks_root
198
265
  File.join(contents_root, 'Frameworks')
199
266
  end
200
267
 
268
+ ##
269
+ # Path where to put the `MacOS' directory of the bundle.
201
270
  def macos_root
202
271
  File.join(contents_root, 'MacOS')
203
272
  end
204
273
 
274
+ ##
275
+ # Path where to put the `Resources' directory of the bundle.
205
276
  def resources_root
206
277
  File.join(contents_root, 'Resources')
207
278
  end
208
279
 
280
+ ##
281
+ # Path where to put the `Info.plist' directory of the bundle.
209
282
  def info_plist_file
210
283
  File.join(contents_root, 'Info.plist')
211
284
  end
212
285
 
286
+ ##
287
+ # Path where to put the icon for the bundle.
213
288
  def icon_file
214
289
  File.join(resources_root, "#{spec.name}.icns")
215
290
  end
216
291
 
292
+ ##
293
+ # Path where to put the `PkgInfo` file for the bundle.
217
294
  def pkg_info_file
218
295
  File.join(contents_root, 'PkgInfo')
219
296
  end
220
297
 
298
+ ##
299
+ # Generate the name of the binary. Done by removing whitespace from
300
+ # the `name` attribute of the cached app spec.
221
301
  def executable_file_name
222
302
  spec.name.gsub(/\s+/, '')
223
303
  end
224
304
 
305
+ ##
306
+ # Path where to put the binary file for the bundle.
225
307
  def executable_file
226
308
  File.join(macos_root, executable_file_name)
227
309
  end
228
310
 
311
+ ##
312
+ # Temporary path where the temporary source for bootstrap binary.
229
313
  def objective_c_source_file
230
314
  File.join(macos_root, 'main.m')
231
315
  end
232
316
 
317
+ ##
318
+ # Path where to put the `rb_main.rb` bootstrap file.
233
319
  def main_ruby_source_file
234
320
  File.join(resources_root, 'rb_main.rb')
235
321
  end
@@ -127,7 +127,7 @@ module Application
127
127
  # Empty by default.
128
128
  #
129
129
  # @return [Hash]
130
- # attr_accessor :plist
130
+ attr_accessor :plist
131
131
 
132
132
  # @todo Support localization related plist keys natively
133
133
  # @todo CFBundleDevelopmentRegion (Recommended)
@@ -154,7 +154,7 @@ module Application
154
154
  # @return [Array<String>]
155
155
  attr_accessor :data_models
156
156
 
157
- # @group Deloyment Options
157
+ # @group Deployment Options
158
158
 
159
159
  ##
160
160
  # Whether to include the Ruby stdlib in the app when embedding
@@ -244,8 +244,6 @@ module Application
244
244
  alias_method :embed_bs?, :embed_bs
245
245
 
246
246
  ##
247
- # @todo Is this actually useful or can we get rid of it?
248
- #
249
247
  # Whether or not to always make a clean build of the app.
250
248
  #
251
249
  # Defaults to false.
@@ -257,7 +255,7 @@ module Application
257
255
  # @endgroup
258
256
 
259
257
  DEFAULT_ATTRIBUTES = {
260
- # plist: {}, # @todo Finish this before release
258
+ plist: {},
261
259
  sources: [],
262
260
  resources: [],
263
261
  data_models: [],
@@ -281,8 +279,6 @@ module Application
281
279
  end
282
280
  yield self
283
281
 
284
- # @todo go through plist and overwrite specific keys?
285
-
286
282
  # @todo should we verify at initialization or defer until building?
287
283
  verify!
288
284
  end
@@ -342,7 +338,6 @@ module Application
342
338
  @copyright = @copyright.to_s if @copyright
343
339
  end
344
340
 
345
- # @todo Should a warning be given if not embedding the stdlib?
346
341
  def verify_stdlib
347
342
  # need to be careful here; the main components of hotcocoa do
348
343
  # not depend on the stdlib right now, but if that changes then
@@ -302,7 +302,6 @@ module HotCocoa
302
302
  puts `macruby_deploy --embed --gem hotcocoa #{options} #{bundle_root}`
303
303
  end
304
304
 
305
- # @todo something better than puts `gcc`
306
305
  def build_executable
307
306
  File.open(objective_c_source_file, 'wb') do |f|
308
307
  f.write %{
@@ -315,7 +314,7 @@ module HotCocoa
315
314
  }
316
315
  end
317
316
  Dir.chdir(macos_root) do
318
- puts `gcc main.m -o #{objective_c_executable_file} -arch x86_64 -framework MacRuby -framework Foundation -fobjc-gc-only`
317
+ puts `#{RbConfig::CONFIG['CC']} main.m -o #{objective_c_executable_file} -arch x86_64 -framework MacRuby -framework Foundation -fobjc-gc-only`
319
318
  end
320
319
  File.unlink(objective_c_source_file)
321
320
  end
@@ -16,8 +16,12 @@ HotCocoa::Mappings.map tracking_area: NSTrackingArea do
16
16
 
17
17
  def init_with_options tracking_area, options
18
18
  rect = options.delete(:rect)
19
+ widget_options = options.delete(:options)
20
+ if widget_options.nil?
21
+ raise ArgumentError.new("Options must be set for NSTrackingArea, in particular the type of tracking area")
22
+ end
19
23
  tracking_area.initWithRect rect,
20
- options: options.delete(:options),
24
+ options: widget_options,
21
25
  owner: options.delete(:owner),
22
26
  userInfo: nil
23
27
  end
@@ -39,7 +39,7 @@ class HotCocoa::NotificationListener
39
39
 
40
40
  class << self
41
41
  ##
42
- # List of all {HotCocoa::NotificationListeners}.
42
+ # List of all {HotCocoa::NotificationListener}s.
43
43
  #
44
44
  # @return [HotCocoa::NotificationListener]
45
45
  attr_reader :registered_listeners
@@ -66,22 +66,32 @@ class HotCocoa::NotificationListener
66
66
  # notification
67
67
  # @yieldparam [String] notification the name of the notification received
68
68
  def initialize options = {}, &block
69
- raise 'You must pass a block to act as the callback' unless block_given?
69
+ unless block_given?
70
+ raise ArgumentError, 'You must pass a block to act as the callback'
71
+ end
70
72
  @callback = block
71
73
 
72
74
  @name = options[:named]
73
75
  @sender = options[:sent_by]
74
76
  @suspension_behavior = DistributedBehaviors[options[:when_suspended] || :coalesce]
75
77
  @distributed = (options[:distributed] == true)
76
- NotificationListener.registered_listeners << self
78
+ self.class.registered_listeners << self
77
79
  observe
78
80
  end
79
81
 
82
+ ##
83
+ # (see #stop_listening)
84
+ # @deprecated Use {#stop_listening} instead. This API is scheduled to
85
+ # be removed in HotCocoa 0.7.
86
+ def stop_notifications options = {}
87
+ stop_listening options
88
+ end
89
+
80
90
  ##
81
91
  # Stop the listener from listening to any future notifications. The
82
92
  # options available here are the same as the {#initialize} methods
83
93
  # `:named` and `:sent_by` options.
84
- def stop_notifications options = {}
94
+ def stop_listening options = {}
85
95
  if options.has_key?(:named) || options.has_key?(:sent_by)
86
96
  notification_center.removeObserver self,
87
97
  name: options[:named],
@@ -89,6 +99,7 @@ class HotCocoa::NotificationListener
89
99
  else
90
100
  notification_center.removeObserver self
91
101
  end
102
+ self.class.registered_listeners.delete self
92
103
  end
93
104
 
94
105
  ##
@@ -0,0 +1,30 @@
1
+ require 'hotcocoa/application/builder'
2
+
3
+ builder = Application::Builder.new APPSPEC
4
+
5
+ desc 'Build the application'
6
+ task :build do
7
+ builder.build
8
+ end
9
+
10
+ desc 'Build a deployable version of the application'
11
+ task :deploy do
12
+ builder.build deploy: true
13
+ end
14
+
15
+ desc 'Build and execute the application'
16
+ task :run => [:build] do
17
+ builder.run
18
+ end
19
+
20
+ desc 'Cleanup build files'
21
+ task :clean do
22
+ builder.remove_bundle_root
23
+ end
24
+
25
+ desc 'Create the dmg archive from the application bundle'
26
+ task :dmg => :deploy do
27
+ app_name = builder.spec.name
28
+ rm_rf "#{app_name}.dmg"
29
+ sh "hdiutil create #{app_name}.dmg -quiet -srcdir #{app_name}.app -format UDZO -imagekey zlib-level=9"
30
+ end
@@ -1,12 +1,16 @@
1
1
  $stderr.puts <<EOM
2
- standard_rake_tasks.rb is deprecated in favour of a new app template
3
- which declares the tasks directly in the template Rakefile.
2
+ The old build system, which uses standard_rake_tasks.rb is deprecated in favour
3
+ of a more easily configurable build system as of HotCocoa 0.6. The old build
4
+ system will be removed in HotCocoa 0.7.
5
+
6
+ You can update your existing project by looking at the new project template, which
7
+ can be found on Github:
8
+
9
+ https://github.com/ferrous26/hotcocoa/blob/master/template
4
10
 
5
- You can update your Rakefile by copying the new tasks from Github at
6
- https://github.com/ferrous26/hotcocoa/blob/master/template/Rakefile
7
11
  EOM
8
12
 
9
- AppConfig = HotCocoa::ApplicationBuilder::Configuration.new( 'config/build.yml' )
13
+ AppConfig = HotCocoa::ApplicationBuilder::Configuration.new('config/build.yml')
10
14
 
11
15
  desc 'Build a deployable version of the application'
12
16
  task :deploy do
@@ -1,3 +1,3 @@
1
1
  module HotCocoa
2
- VERSION = '0.6.0pre'
2
+ VERSION = '0.6.0pre2'
3
3
  end
data/template/Rakefile CHANGED
@@ -1,33 +1,8 @@
1
- require 'rubygems'
2
- require 'hotcocoa/application/builder'
3
-
4
- builder = Application::Builder.new '__APPLICATION_NAME__.appspec'
5
-
6
- desc 'Build the application'
7
- task :build do
8
- builder.build
9
- end
1
+ APPSPEC = '__APPLICATION_NAME__.appspec'
10
2
 
11
- desc 'Build a deployable version of the application'
12
- task :deploy do
13
- builder.build deploy: true
14
- end
15
-
16
- desc 'Build and execute the application'
17
- task :run => [:build] do
18
- builder.run
19
- end
20
-
21
- desc 'Cleanup build files'
22
- task :clean do
23
- builder.remove_bundle_root
24
- end
3
+ require 'rubygems'
4
+ require 'hotcocoa/rake_tasks'
25
5
 
26
- desc 'Create the dmg archive from the application bundle'
27
- task :dmg => :deploy do
28
- app_name = builder.spec.name
29
- rm_rf "#{app_name}.dmg"
30
- sh "hdiutil create #{app_name}.dmg -quiet -srcdir #{app_name}.app -format UDZO -imagekey zlib-level=9"
31
- end
6
+ task :default => :run
32
7
 
33
- task :default => [:run]
8
+ # Add your own tasks here
@@ -1,8 +1,42 @@
1
+ # for more information about the fields that can be set on the specification, check out the rdoc:
2
+ # http://rdoc.info/github/ferrous26/hotcocoa/master/Application/Specification
3
+ #
1
4
  Application::Specification.new do |s|
2
5
  s.name = '__APPLICATION_NAME__'
3
6
  s.identifier = 'com.__COMPANY_NAME__.__APPLICATION_NAME__'
7
+
8
+ # The version of the app, usually including the build number.
4
9
  s.version = '1.0'
10
+
5
11
  s.icon = 'resources/HotCocoa.icns'
6
12
  s.resources = Dir.glob('resources/**/*.*')
7
13
  s.sources = Dir.glob('lib/**/*.rb')
14
+
15
+ # optional copyright
16
+ # s.copyright = "2011, Your Company"
17
+
18
+ # optional short version (in contrast to the full version, the short version should not contain the build number)
19
+ # s.short_version = "$MAJOR.$MINOR.$PATCHLEVEL"
20
+
21
+ # to avoid embedding the standard libs
22
+ # s.stdlib = false
23
+ # alternatively, specify the modules that you wish to include
24
+ # s.stdlib = ['base64', 'matrix', 'set']
25
+
26
+ # specify which gems you wish to be bundled with your application
27
+ # hotcocoa is automatically bundled and doesn't need to be specified here
28
+ # s.gems = ['rest-client']
29
+
30
+ # uncomment if you wish to embed the BridgeSupport files during deployment
31
+ # useful if you need to deploy the app to OS X 10.6.
32
+ # s.embed_bs = true
33
+
34
+ # uncomment to always make a clean build of the app
35
+ # s.overwrite = true
36
+
37
+ # toggle whether the app is an daemon with UI or a regular app
38
+ # You can use this flag to hide the dock icon for the app; the
39
+ # default value is false so that apps will have a dock icon
40
+ # s.agent = true
8
41
  end
42
+
@@ -0,0 +1,21 @@
1
+ require 'hotcocoa/application/builder'
2
+
3
+ class TestApplicationModule < MiniTest::Unit::TestCase
4
+ include Application
5
+
6
+ def hotconsole_spec
7
+ @@hotconsole_spec ||= Specification.load 'test/fixtures/hotconsole.appspec'
8
+ end
9
+ def stopwatch_spec
10
+ @@stopwatch_spec ||= Specification.load 'test/fixtures/stopwatch.appspec'
11
+ end
12
+
13
+ def minimal_spec
14
+ Specification.new do |s|
15
+ s.name = 'test'
16
+ s.identifier = 'com.test.test'
17
+ yield s if block_given?
18
+ end
19
+ end
20
+
21
+ end
@@ -1,28 +1,71 @@
1
- require 'hotcocoa/application/builder'
1
+ require 'test/application/helper'
2
2
 
3
- class TestApplicationBuilder < MiniTest::Unit::TestCase
4
- include Application
3
+ class TestApplicationBuilder < TestApplicationModule
5
4
 
6
- TEST_DIR = File.join(ENV['TMPDIR'], 'test_app_specification')
5
+ def hotconsole
6
+ @@hotconsole ||= Builder.new hotconsole_spec
7
+ end
8
+ def stopwatch
9
+ @@stopwatch ||= Builder.new stopwatch_spec
10
+ end
11
+
12
+ def test_caches_spec
13
+ assert_equal stopwatch_spec, stopwatch.spec
14
+ end
7
15
 
8
- # Some HotCocoa appspec files, converted from build.yml files borrowed from projects on Github
9
- HOTCONSOLE = 'test/fixtures/hotconsole.appspec'
10
- STOPWATCH = 'test/fixtures/stopwatch.appspec'
16
+ # I don't think it is too important to test deployment as well
17
+ # as long as we make sure we are passing the correct options
18
+ # to `macruby_deploy`
11
19
 
12
- def setup; FileUtils.mkdir TEST_DIR; end
13
- def teardown; FileUtils.rm_rf TEST_DIR; end
20
+ def test_deploy_option_gems
21
+ assert_includes stopwatch.send(:deploy_options), '--gem rest-client'
22
+ refute_includes hotconsole.send(:deploy_options), '--gem'
23
+ end
14
24
 
15
- def test_caches_spec
16
- spec = Specification.load STOPWATCH
17
- builder = Builder.new spec
18
- assert_equal spec, builder.spec
25
+ def test_deploy_option_compile
26
+ assert_includes stopwatch.send(:deploy_options), '--compile'
27
+ refute_includes hotconsole.send(:deploy_options), '--compile'
28
+ end
29
+
30
+ def test_deploy_option_embed_bs
31
+ refute_includes stopwatch.send(:deploy_options), '--bs'
32
+ assert_includes hotconsole.send(:deploy_options), '--bs'
33
+ end
34
+
35
+ def test_deploy_option_stdlib
36
+ assert_includes stopwatch.send(:deploy_options), '--no-stdlib'
37
+ refute_includes hotconsole.send(:deploy_options), 'stdlib'
38
+
39
+ spec = minimal_spec do |s|
40
+ s.stdlib = ['matrix', 'base64']
41
+ end
42
+ options = Builder.new(spec).send :deploy_options
43
+ refute_includes options, '--no-stdlib'
44
+ assert_includes options, '--stdlib matrix'
45
+ assert_includes options, '--stdlib base64'
19
46
  end
20
47
 
21
- def test_deploy_options
22
- spec = Specification.load STOPWATCH
23
- builder = Builder.new spec
24
- options = builder.send :deploy_options
25
- assert options.include? "--gem rest-client"
48
+ def test_plist_only_uses_icon_if_it_can
49
+ plist = load_plist(hotconsole.send(:info_plist))
50
+ refute_includes plist, :CFBundleIconFile
51
+
52
+ spec = hotconsole_spec.dup
53
+ spec.icon = '/Applications/Calculator.app/Contents/Resources/Calculator.icns'
54
+ plist = load_plist(Builder.new(spec).send(:info_plist))
55
+ assert_includes plist, :CFBundleIconFile
56
+ end
57
+
58
+ def test_plist_hash_from_spec_overrides_all
59
+ spec = hotconsole_spec.dup
60
+ spec.plist[:MyKey] = true
61
+ spec.plist[:NSPrincipleClass] = 'Foo'
62
+ spec.plist[:CFBundleName] = 'Cake'
63
+
64
+ plist = load_plist(Builder.new(spec).send(:info_plist))
65
+ assert_equal true, plist[:MyKey ]
66
+ assert_equal 'Foo', plist[:NSPrincipleClass ]
67
+ assert_equal 'Cake', plist[:CFBundleName ]
68
+ assert_equal spec.identifier, plist[:CFBundleIdentifier]
26
69
  end
27
70
 
28
71
  end
@@ -1,11 +1,6 @@
1
- require 'hotcocoa/application/specification'
1
+ require 'test/application/helper'
2
2
 
3
- class TestApplicationSpecification < MiniTest::Unit::TestCase
4
- include Application
5
-
6
- # Some HotCocoa appspec files, converted from build.yml files borrowed from projects on Github
7
- HOTCONSOLE = 'test/fixtures/hotconsole.appspec'
8
- STOPWATCH = 'test/fixtures/stopwatch.appspec'
3
+ class TestApplicationSpecification < TestApplicationModule
9
4
 
10
5
  def rescue_spec_error_for &block
11
6
  begin
@@ -15,14 +10,6 @@ class TestApplicationSpecification < MiniTest::Unit::TestCase
15
10
  end
16
11
  end
17
12
 
18
- def minimal_spec
19
- Specification.new do |s|
20
- s.name = 'test'
21
- s.identifier = 'com.test.test'
22
- yield s if block_given?
23
- end
24
- end
25
-
26
13
  def test_spec_requires_a_block
27
14
  error = rescue_spec_error_for # no block given
28
15
  assert_match /must pass a block/, error.message
@@ -259,7 +246,7 @@ class TestApplicationSpecification < MiniTest::Unit::TestCase
259
246
 
260
247
  # doubles as an integration test
261
248
  def test_load_evaluates_files_properly
262
- spec = Application::Specification.load HOTCONSOLE
249
+ spec = hotconsole_spec
263
250
  assert_equal 'HotConsole', spec.name
264
251
  assert_equal 'com.vincentisambart.HotConsole', spec.identifier
265
252
  assert_equal '1.0', spec.version
@@ -267,7 +254,7 @@ class TestApplicationSpecification < MiniTest::Unit::TestCase
267
254
  assert_equal [], spec.resources
268
255
  assert_equal 'girb', spec.signature
269
256
 
270
- spec = Application::Specification.load STOPWATCH
257
+ spec = stopwatch_spec
271
258
  assert_equal 'Stopwatch', spec.name
272
259
  assert_equal 'nz.co.kearse.stopwatch', spec.identifier
273
260
  assert_equal Dir.glob('{lib,hotcocoa}*/**/*.rb'), spec.sources
@@ -76,4 +76,13 @@ class TestBonjourMappings < MiniTest::Unit::TestCase
76
76
  skip 'TODO'
77
77
  end
78
78
 
79
+ def bench_delegate_building
80
+ browser = bonjour_browser
81
+ assert_performance_linear do |n|
82
+ n.times do
83
+ browser.did_find_service { |_,_| }
84
+ end
85
+ end
86
+ end
87
+
79
88
  end
@@ -12,7 +12,7 @@ class TestTrackingAreaMappings < MiniTest::Unit::TestCase
12
12
 
13
13
  def bench_create_tracking_area
14
14
  assert_performance_linear do |n|
15
- n.times { HotCocoa.tracking_area }
15
+ n.times { HotCocoa.tracking_area(options: [:mouse_entered_and_exited, :active_first_responder]) }
16
16
  end
17
17
  end
18
18
  end
@@ -6,90 +6,80 @@ require 'hotcocoa/application_builder'
6
6
  class TestConfiguration < MiniTest::Unit::TestCase
7
7
 
8
8
  Configuration = HotCocoa::ApplicationBuilder::Configuration
9
- TEST_DIR = File.join( ENV['TMPDIR'], 'test_app_builder' )
9
+ TEST_DIR = File.join(ENV['TMPDIR'], 'test_app_builder')
10
10
 
11
11
  # Some HotCocoa build.yml files, borrowed from projects on Github
12
- HOTCONSOLE = 'test/fixtures/hotconsole.yml'
13
- CALCULATOR = 'test/fixtures/calculator.yml'
14
- STOPWATCH = 'test/fixtures/stopwatch.yml'
15
- EMPTY_APP = 'test/fixtures/empty.yml'
12
+ def hotconsole_config
13
+ @@hotconsole_config ||= Configuration.new 'test/fixtures/hotconsole.yml'
14
+ end
15
+ def calculator_config
16
+ @@calculator_config ||= Configuration.new 'test/fixtures/calculator.yml'
17
+ end
18
+ def stopwatch_config
19
+ @@stopwatch_config ||= Configuration.new 'test/fixtures/stopwatch.yml'
20
+ end
21
+ def empty_config
22
+ @@empty_config ||= Configuration.new 'test/fixtures/empty.yml'
23
+ end
16
24
 
17
25
  def setup; FileUtils.mkdir TEST_DIR; end
18
26
  def teardown; FileUtils.rm_rf TEST_DIR; end
19
27
 
20
28
  def test_reads_attributes
21
- conf = Configuration.new HOTCONSOLE
29
+ conf = hotconsole_config
22
30
  assert_equal 'HotConsole', conf.name
23
31
  assert_equal '1.0', conf.version
24
32
  assert_equal 'resources/HotConsole.icns', conf.icon
25
33
  assert_equal ['resources/**/*.*'], conf.resources
26
34
  assert_equal ['lib/**/*.rb'], conf.sources
27
35
 
28
- conf = Configuration.new CALCULATOR
36
+ conf = calculator_config
29
37
  assert_equal 'Calculator', conf.name
30
38
  assert_equal '2.0', conf.version
31
39
  end
32
40
 
33
41
  def test_version_defaults_to_1_if_not_set
34
- conf = Configuration.new STOPWATCH
42
+ conf = stopwatch_config
35
43
  refute_nil conf.version
36
44
  assert_equal '1.0', conf.version
37
45
  end
38
46
 
39
47
  def test_sources_resources_and_data_models_are_initialized_to_an_empty_array_if_not_provided
40
- conf = Configuration.new EMPTY_APP
48
+ conf = empty_config
41
49
  assert_empty conf.sources
42
50
  assert_empty conf.resources
43
51
  assert_empty conf.data_models
44
52
  end
45
53
 
46
54
  def test_overwirte_attribute
47
- conf = Configuration.new EMPTY_APP
48
- refute conf.overwrite?
49
-
50
- conf = Configuration.new STOPWATCH
51
- assert conf.overwrite?
55
+ refute empty_config.overwrite?
56
+ assert stopwatch_config.overwrite?
52
57
  end
53
58
 
54
59
  def test_agent_attribute
55
- conf = Configuration.new EMPTY_APP
56
- assert_equal '0', conf.agent
57
-
58
- conf = Configuration.new STOPWATCH
59
- assert_equal '1', conf.agent
60
+ assert_equal '0', empty_config.agent
61
+ assert_equal '1', stopwatch_config.agent
60
62
  end
61
63
 
62
64
  def test_stdlib_attribute
63
- conf = Configuration.new HOTCONSOLE
64
- assert_equal true, conf.stdlib
65
-
66
- conf = Configuration.new STOPWATCH
67
- assert_equal false, conf.stdlib
65
+ assert_equal true, hotconsole_config.stdlib
66
+ assert_equal false, stopwatch_config.stdlib
68
67
  end
69
68
 
70
69
  def test_type_attribute
71
- conf = Configuration.new HOTCONSOLE
72
- assert_equal 'APPL', conf.type
73
-
74
- conf = Configuration.new EMPTY_APP
75
- assert_equal 'BNDL', conf.type
70
+ assert_equal 'APPL', hotconsole_config.type
71
+ assert_equal 'BNDL', empty_config.type
76
72
  end
77
73
 
78
74
  def test_signature_attribute
79
- conf = Configuration.new EMPTY_APP
80
- assert_equal '????', conf.signature
81
-
82
- conf = Configuration.new HOTCONSOLE
83
- assert_equal 'girb', conf.signature
75
+ assert_equal '????', empty_config.signature
76
+ assert_equal 'girb', hotconsole_config.signature
84
77
  end
85
78
 
86
79
  def test_icon_exists?
87
- conf = Configuration.new HOTCONSOLE
88
- refute conf.icon_exists?
89
-
90
- # works because this project uses the icon from a system app
91
- conf = Configuration.new CALCULATOR
92
- assert conf.icon_exists?
80
+ refute hotconsole_config.icon_exists?
81
+ # works on all Macs because this project uses the icon from a system app
82
+ assert calculator_config.icon_exists?
93
83
  end
94
84
 
95
85
  end
@@ -1,19 +1,48 @@
1
1
  # Integration tests
2
2
  class TestNotificationListener < MiniTest::Unit::TestCase
3
+ include HotCocoa
3
4
 
4
- def test_
5
+ def teardown
6
+ NotificationListener.registered_listeners.each &:stop_listening
5
7
  end
6
8
 
7
- def test_
9
+ def test_requires_a_block
10
+ assert_raises ArgumentError do
11
+ NotificationListener.new
12
+ end
8
13
  end
9
14
 
10
- def test_
15
+ def test_caches_listeners
16
+ listener = NotificationListener.new { |_| }
17
+ assert_includes NotificationListener.registered_listeners, listener
11
18
  end
12
19
 
13
- def test_
20
+ def test_executes_block_when_notif_is_received
21
+ got_callback = false
22
+ NotificationListener.new named: 'test' do |_|
23
+ got_callback = true
24
+ end
25
+ NSNotificationCenter.defaultCenter.postNotificationName 'test',
26
+ object: self
27
+ assert got_callback
14
28
  end
15
29
 
16
- def test_
30
+ def test_can_stop_listening
31
+ got_callback = false
32
+ listener = NotificationListener.new named: 'test2' do |_|
33
+ got_callback = true
34
+ end
35
+ listener.stop_listening
36
+ NSNotificationCenter.defaultCenter.postNotificationName 'test2',
37
+ object: self
38
+
39
+ refute_includes NotificationListener.registered_listeners, listener
40
+ refute got_callback
41
+ end
42
+
43
+ def test_on_notification_is_alias
44
+ listener = ::HotCocoa.on_notification { |_| }
45
+ assert_kind_of NotificationListener, listener
17
46
  end
18
47
 
19
48
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: hotcocoa
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 5
5
- version: 0.6.0pre
5
+ version: 0.6.0pre2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Richard Kilmer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-10-04 00:00:00 -04:00
13
+ date: 2011-10-08 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -168,6 +168,7 @@ files:
168
168
  - lib/hotcocoa/mappings.rb
169
169
  - lib/hotcocoa/mvc.rb
170
170
  - lib/hotcocoa/notification_listener.rb
171
+ - lib/hotcocoa/rake_tasks.rb
171
172
  - lib/hotcocoa/standard_rake_tasks.rb
172
173
  - lib/hotcocoa/target_action_convenience.rb
173
174
  - lib/hotcocoa/template.rb
@@ -178,6 +179,7 @@ files:
178
179
  - template/lib/menu.rb
179
180
  - template/Rakefile
180
181
  - template/resources/HotCocoa.icns
182
+ - test/application/helper.rb
181
183
  - test/application/test_builder.rb
182
184
  - test/application/test_specification.rb
183
185
  - test/core_extensions/test_kernel.rb
@@ -237,6 +239,7 @@ signing_key:
237
239
  specification_version: 3
238
240
  summary: Cocoa mapping library for MacRuby
239
241
  test_files:
242
+ - test/application/helper.rb
240
243
  - test/application/test_builder.rb
241
244
  - test/application/test_specification.rb
242
245
  - test/core_extensions/test_kernel.rb