hotcocoa 0.6.0pre → 0.6.0pre2

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.
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