hotcocoa 0.5.1 → 0.6.0pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +14 -0
- data/History.txt +21 -0
- data/README.markdown +84 -0
- data/Rakefile +47 -0
- data/bin/hotcocoa +20 -10
- data/docs/Contributors.markdown +25 -0
- data/docs/Mappings.markdown +352 -0
- data/docs/MappingsExplained.markdown +22 -0
- data/docs/Overview.markdown +58 -0
- data/docs/Resources.markdown +25 -0
- data/docs/Tutorial.markdown +3 -0
- data/lib/hotcocoa/application/builder.rb +237 -0
- data/lib/hotcocoa/application/specification.rb +373 -0
- data/lib/hotcocoa/application_builder.rb +338 -242
- data/lib/hotcocoa/attributed_string_helpers.rb +128 -0
- data/lib/hotcocoa/behaviors.rb +39 -6
- data/lib/hotcocoa/core_extensions/kernel.rb +67 -0
- data/lib/hotcocoa/core_extensions/nsarray.rb +15 -0
- data/lib/hotcocoa/core_extensions/nsmutable_attributed_string.rb +74 -0
- data/lib/hotcocoa/core_extensions/nsstring.rb +36 -0
- data/lib/hotcocoa/core_extensions/nsurl.rb +6 -0
- data/lib/hotcocoa/core_extensions/numeric.rb +9 -0
- data/lib/hotcocoa/core_extensions/object.rb +36 -0
- data/lib/hotcocoa/core_extensions/range.rb +30 -0
- data/lib/hotcocoa/core_extensions.rb +8 -0
- data/lib/hotcocoa/data_sources/combo_box_data_source.rb +38 -38
- data/lib/hotcocoa/data_sources/outline_view_data_source.rb +33 -0
- data/lib/hotcocoa/data_sources/table_data_source.rb +12 -13
- data/lib/hotcocoa/data_sources.rb +3 -0
- data/lib/hotcocoa/delegate_builder.rb +114 -79
- data/lib/hotcocoa/graphics/canvas.rb +211 -214
- data/lib/hotcocoa/graphics/color.rb +89 -91
- data/lib/hotcocoa/graphics/elements/particle.rb +16 -19
- data/lib/hotcocoa/graphics/elements/rope.rb +12 -14
- data/lib/hotcocoa/graphics/elements/sandpainter.rb +11 -13
- data/lib/hotcocoa/graphics/gradient.rb +13 -14
- data/lib/hotcocoa/graphics/image.rb +110 -83
- data/lib/hotcocoa/graphics/path.rb +44 -50
- data/lib/hotcocoa/graphics/pdf.rb +17 -19
- data/lib/hotcocoa/graphics.rb +21 -20
- data/lib/hotcocoa/kvo_accessors.rb +10 -11
- data/lib/hotcocoa/layout_view.rb +394 -379
- data/lib/hotcocoa/mapper.rb +346 -207
- data/lib/hotcocoa/mapping_methods.rb +107 -37
- data/lib/hotcocoa/mappings/appkit/alert.rb +25 -0
- data/lib/hotcocoa/mappings/appkit/application.rb +112 -0
- data/lib/hotcocoa/mappings/{array_controller.rb → appkit/array_controller.rb} +33 -35
- data/lib/hotcocoa/mappings/appkit/box.rb +37 -0
- data/lib/hotcocoa/mappings/appkit/button.rb +88 -0
- data/lib/hotcocoa/mappings/appkit/collection_view.rb +42 -0
- data/lib/hotcocoa/mappings/appkit/color.rb +40 -0
- data/lib/hotcocoa/mappings/appkit/column.rb +19 -0
- data/lib/hotcocoa/mappings/appkit/combo_box.rb +22 -0
- data/lib/hotcocoa/mappings/appkit/control.rb +31 -0
- data/lib/hotcocoa/mappings/appkit/font.rb +58 -0
- data/lib/hotcocoa/mappings/appkit/gradient.rb +19 -0
- data/lib/hotcocoa/mappings/appkit/image.rb +15 -0
- data/lib/hotcocoa/mappings/appkit/image_view.rb +41 -0
- data/lib/hotcocoa/mappings/appkit/label.rb +23 -0
- data/lib/hotcocoa/mappings/appkit/layout_view.rb +9 -0
- data/lib/hotcocoa/mappings/appkit/line.rb +16 -0
- data/lib/hotcocoa/mappings/appkit/menu.rb +78 -0
- data/lib/hotcocoa/mappings/appkit/menu_item.rb +47 -0
- data/lib/hotcocoa/mappings/appkit/outline_view.rb +62 -0
- data/lib/hotcocoa/mappings/appkit/popup.rb +106 -0
- data/lib/hotcocoa/mappings/appkit/progress_indicator.rb +61 -0
- data/lib/hotcocoa/mappings/appkit/scroll_view.rb +28 -0
- data/lib/hotcocoa/mappings/appkit/search_field.rb +9 -0
- data/lib/hotcocoa/mappings/appkit/secure_text_field.rb +15 -0
- data/lib/hotcocoa/mappings/appkit/segmented_control.rb +103 -0
- data/lib/hotcocoa/mappings/appkit/slider.rb +23 -0
- data/lib/hotcocoa/mappings/appkit/sound.rb +9 -0
- data/lib/hotcocoa/mappings/appkit/speech_synthesizer.rb +22 -0
- data/lib/hotcocoa/mappings/appkit/split_view.rb +19 -0
- data/lib/hotcocoa/mappings/appkit/status_bar.rb +7 -0
- data/lib/hotcocoa/mappings/appkit/status_item.rb +9 -0
- data/lib/hotcocoa/mappings/appkit/table_view.rb +108 -0
- data/lib/hotcocoa/mappings/appkit/text_field.rb +36 -0
- data/lib/hotcocoa/mappings/appkit/text_view.rb +13 -0
- data/lib/hotcocoa/mappings/appkit/toolbar.rb +99 -0
- data/lib/hotcocoa/mappings/appkit/toolbar_item.rb +36 -0
- data/lib/hotcocoa/mappings/appkit/tracking_area.rb +24 -0
- data/lib/hotcocoa/mappings/appkit/view.rb +65 -0
- data/lib/hotcocoa/mappings/appkit/window.rb +124 -0
- data/lib/hotcocoa/mappings/foundation/net_service.rb +65 -0
- data/lib/hotcocoa/mappings/foundation/net_service_browser.rb +27 -0
- data/lib/hotcocoa/mappings/foundation/notification.rb +24 -0
- data/lib/hotcocoa/mappings/foundation/sort_descriptor.rb +17 -0
- data/lib/hotcocoa/mappings/foundation/timer.rb +38 -0
- data/lib/hotcocoa/mappings/foundation/user_defaults.rb +43 -0
- data/lib/hotcocoa/mappings/foundation/xml_parser.rb +44 -0
- data/lib/hotcocoa/mappings/qtkit/movie.rb +15 -0
- data/lib/hotcocoa/mappings/qtkit/movie_view.rb +28 -0
- data/lib/hotcocoa/mappings/webkit/web_view.rb +20 -0
- data/lib/hotcocoa/mappings.rb +57 -111
- data/lib/hotcocoa/mvc.rb +90 -81
- data/lib/hotcocoa/notification_listener.rb +135 -58
- data/lib/hotcocoa/standard_rake_tasks.rb +17 -9
- data/lib/hotcocoa/target_action_convenience.rb +39 -0
- data/lib/hotcocoa/template.rb +90 -21
- data/lib/hotcocoa/version.rb +3 -0
- data/lib/hotcocoa.rb +12 -14
- data/template/Rakefile +31 -3
- data/template/__APPLICATION_NAME__.appspec +8 -0
- data/template/lib/application.rb +14 -17
- data/template/lib/menu.rb +11 -11
- data/test/application/test_builder.rb +28 -0
- data/test/application/test_specification.rb +280 -0
- data/test/core_extensions/test_kernel.rb +66 -0
- data/test/core_extensions/test_nsarray.rb +9 -0
- data/test/core_extensions/test_nsmutable_attributed_string.rb +86 -0
- data/test/core_extensions/test_nsstring.rb +20 -0
- data/test/core_extensions/test_nsurl.rb +9 -0
- data/test/core_extensions/test_numeric.rb +10 -0
- data/test/core_extensions/test_object.rb +37 -0
- data/test/core_extensions/test_range.rb +28 -0
- data/test/helper.rb +30 -0
- data/test/mappings/test_bonjour.rb +79 -0
- data/test/mappings/test_color.rb +16 -0
- data/test/mappings/test_font.rb +21 -0
- data/test/mappings/test_tracking_area.rb +18 -0
- data/test/test_application_builder.rb +95 -0
- data/test/test_attributed_string_helpers.rb +63 -0
- data/test/test_behaviours.rb +26 -0
- data/test/test_bin.rb +75 -0
- data/test/test_mapper.rb +100 -0
- data/test/test_mapping_methods.rb +67 -0
- data/test/test_mappings.rb +68 -0
- data/test/test_notification_listener.rb +19 -0
- data/test/test_template.rb +65 -0
- metadata +217 -90
- data/lib/hotcocoa/attributed_string.rb +0 -143
- data/lib/hotcocoa/kernel_ext.rb +0 -14
- data/lib/hotcocoa/mappings/alert.rb +0 -25
- data/lib/hotcocoa/mappings/application.rb +0 -112
- data/lib/hotcocoa/mappings/box.rb +0 -39
- data/lib/hotcocoa/mappings/button.rb +0 -92
- data/lib/hotcocoa/mappings/collection_view.rb +0 -44
- data/lib/hotcocoa/mappings/color.rb +0 -28
- data/lib/hotcocoa/mappings/column.rb +0 -21
- data/lib/hotcocoa/mappings/combo_box.rb +0 -24
- data/lib/hotcocoa/mappings/control.rb +0 -33
- data/lib/hotcocoa/mappings/font.rb +0 -44
- data/lib/hotcocoa/mappings/gradient.rb +0 -15
- data/lib/hotcocoa/mappings/image.rb +0 -15
- data/lib/hotcocoa/mappings/image_view.rb +0 -43
- data/lib/hotcocoa/mappings/label.rb +0 -25
- data/lib/hotcocoa/mappings/layout_view.rb +0 -9
- data/lib/hotcocoa/mappings/menu.rb +0 -71
- data/lib/hotcocoa/mappings/menu_item.rb +0 -47
- data/lib/hotcocoa/mappings/movie.rb +0 -13
- data/lib/hotcocoa/mappings/movie_view.rb +0 -27
- data/lib/hotcocoa/mappings/notification.rb +0 -17
- data/lib/hotcocoa/mappings/popup.rb +0 -110
- data/lib/hotcocoa/mappings/progress_indicator.rb +0 -68
- data/lib/hotcocoa/mappings/scroll_view.rb +0 -29
- data/lib/hotcocoa/mappings/search_field.rb +0 -9
- data/lib/hotcocoa/mappings/secure_text_field.rb +0 -17
- data/lib/hotcocoa/mappings/segmented_control.rb +0 -97
- data/lib/hotcocoa/mappings/slider.rb +0 -25
- data/lib/hotcocoa/mappings/sort_descriptor.rb +0 -13
- data/lib/hotcocoa/mappings/sound.rb +0 -9
- data/lib/hotcocoa/mappings/speech_synthesizer.rb +0 -25
- data/lib/hotcocoa/mappings/split_view.rb +0 -21
- data/lib/hotcocoa/mappings/status_bar.rb +0 -7
- data/lib/hotcocoa/mappings/status_item.rb +0 -9
- data/lib/hotcocoa/mappings/table_view.rb +0 -110
- data/lib/hotcocoa/mappings/text_field.rb +0 -41
- data/lib/hotcocoa/mappings/text_view.rb +0 -13
- data/lib/hotcocoa/mappings/timer.rb +0 -25
- data/lib/hotcocoa/mappings/toolbar.rb +0 -100
- data/lib/hotcocoa/mappings/toolbar_item.rb +0 -36
- data/lib/hotcocoa/mappings/view.rb +0 -67
- data/lib/hotcocoa/mappings/web_view.rb +0 -22
- data/lib/hotcocoa/mappings/window.rb +0 -118
- data/lib/hotcocoa/mappings/xml_parser.rb +0 -41
- data/lib/hotcocoa/object_ext.rb +0 -22
- data/lib/hotcocoa/plist.rb +0 -45
- data/template/config/build.yml +0 -8
- data/test/test_helper.rb +0 -3
- data/test/test_hotcocoa.rb +0 -11
data/lib/hotcocoa.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
-
|
4
1
|
framework 'Cocoa'
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
STDOUT.reopen(IO.for_fd(NSFileHandle.fileHandleWithStandardError.fileDescriptor.to_i, 'w'))
|
4
|
+
|
5
|
+
##
|
6
|
+
# HotCocoa is a Cocoa mapping library for MacRuby. It simplifies the use
|
7
|
+
# of complex Cocoa classes using DSL techniques.
|
8
|
+
module HotCocoa; end
|
10
9
|
|
11
|
-
require 'hotcocoa/
|
12
|
-
require 'hotcocoa/
|
10
|
+
require 'hotcocoa/version'
|
11
|
+
require 'hotcocoa/core_extensions'
|
13
12
|
require 'hotcocoa/mappings'
|
13
|
+
require 'hotcocoa/target_action_convenience'
|
14
14
|
require 'hotcocoa/behaviors'
|
15
15
|
require 'hotcocoa/mapping_methods'
|
16
16
|
require 'hotcocoa/mapper'
|
17
17
|
require 'hotcocoa/layout_view'
|
18
18
|
require 'hotcocoa/delegate_builder'
|
19
19
|
require 'hotcocoa/notification_listener'
|
20
|
-
require 'hotcocoa/data_sources
|
21
|
-
require 'hotcocoa/data_sources/combo_box_data_source'
|
22
|
-
require 'hotcocoa/plist'
|
20
|
+
require 'hotcocoa/data_sources'
|
23
21
|
require 'hotcocoa/kvo_accessors'
|
24
|
-
require 'hotcocoa/
|
22
|
+
require 'hotcocoa/attributed_string_helpers'
|
25
23
|
|
26
|
-
HotCocoa::Mappings.reload
|
24
|
+
HotCocoa::Mappings.reload
|
data/template/Rakefile
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'hotcocoa/
|
3
|
-
require 'hotcocoa/standard_rake_tasks'
|
2
|
+
require 'hotcocoa/application/builder'
|
4
3
|
|
5
|
-
|
4
|
+
builder = Application::Builder.new '__APPLICATION_NAME__.appspec'
|
5
|
+
|
6
|
+
desc 'Build the application'
|
7
|
+
task :build do
|
8
|
+
builder.build
|
9
|
+
end
|
10
|
+
|
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
|
25
|
+
|
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
|
32
|
+
|
33
|
+
task :default => [:run]
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Application::Specification.new do |s|
|
2
|
+
s.name = '__APPLICATION_NAME__'
|
3
|
+
s.identifier = 'com.__COMPANY_NAME__.__APPLICATION_NAME__'
|
4
|
+
s.version = '1.0'
|
5
|
+
s.icon = 'resources/HotCocoa.icns'
|
6
|
+
s.resources = Dir.glob('resources/**/*.*')
|
7
|
+
s.sources = Dir.glob('lib/**/*.rb')
|
8
|
+
end
|
data/template/lib/application.rb
CHANGED
@@ -1,45 +1,42 @@
|
|
1
|
-
require 'rubygems'
|
1
|
+
require 'rubygems' # disable this for a deployed application
|
2
2
|
require 'hotcocoa'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
class Application
|
7
|
-
|
4
|
+
class __APPLICATION_NAME__
|
8
5
|
include HotCocoa
|
9
|
-
|
6
|
+
|
10
7
|
def start
|
11
|
-
application :
|
8
|
+
application name: '__APPLICATION_NAME__' do |app|
|
12
9
|
app.delegate = self
|
13
|
-
window :
|
14
|
-
win << label(:
|
10
|
+
window frame: [100, 100, 500, 500], title: '__APPLICATION_NAME__' do |win|
|
11
|
+
win << label(text: 'Hello from HotCocoa', layout: {start: false})
|
15
12
|
win.will_close { exit }
|
16
13
|
end
|
17
14
|
end
|
18
15
|
end
|
19
|
-
|
16
|
+
|
20
17
|
# file/open
|
21
18
|
def on_open(menu)
|
22
19
|
end
|
23
|
-
|
24
|
-
# file/new
|
20
|
+
|
21
|
+
# file/new
|
25
22
|
def on_new(menu)
|
26
23
|
end
|
27
|
-
|
24
|
+
|
28
25
|
# help menu item
|
29
26
|
def on_help(menu)
|
30
27
|
end
|
31
|
-
|
28
|
+
|
32
29
|
# This is commented out, so the minimize menu item is disabled
|
33
30
|
#def on_minimize(menu)
|
34
31
|
#end
|
35
|
-
|
32
|
+
|
36
33
|
# window/zoom
|
37
34
|
def on_zoom(menu)
|
38
35
|
end
|
39
|
-
|
36
|
+
|
40
37
|
# window/bring_all_to_front
|
41
38
|
def on_bring_all_to_front(menu)
|
42
39
|
end
|
43
40
|
end
|
44
41
|
|
45
|
-
|
42
|
+
__APPLICATION_NAME__.new.start
|
data/template/lib/menu.rb
CHANGED
@@ -2,30 +2,30 @@ module HotCocoa
|
|
2
2
|
def application_menu
|
3
3
|
menu do |main|
|
4
4
|
main.submenu :apple do |apple|
|
5
|
-
apple.item :about, :
|
5
|
+
apple.item :about, title: "About #{NSApp.name}"
|
6
6
|
apple.separator
|
7
|
-
apple.item :preferences, :
|
7
|
+
apple.item :preferences, key: ','
|
8
8
|
apple.separator
|
9
9
|
apple.submenu :services
|
10
10
|
apple.separator
|
11
|
-
apple.item :hide, :
|
12
|
-
apple.item :hide_others, :
|
13
|
-
apple.item :show_all, :
|
11
|
+
apple.item :hide, title: "Hide #{NSApp.name}", key: 'h'
|
12
|
+
apple.item :hide_others, title: 'Hide Others', key: 'h', modifiers: [:command, :alt]
|
13
|
+
apple.item :show_all, title: 'Show All'
|
14
14
|
apple.separator
|
15
|
-
apple.item :quit, :
|
15
|
+
apple.item :quit, title: "Quit #{NSApp.name}", key: 'q'
|
16
16
|
end
|
17
17
|
main.submenu :file do |file|
|
18
|
-
file.item :new, :
|
19
|
-
file.item :open, :
|
18
|
+
file.item :new, key: 'n'
|
19
|
+
file.item :open, key: 'o'
|
20
20
|
end
|
21
21
|
main.submenu :window do |win|
|
22
|
-
win.item :minimize, :
|
22
|
+
win.item :minimize, key: 'm'
|
23
23
|
win.item :zoom
|
24
24
|
win.separator
|
25
|
-
win.item :bring_all_to_front, :
|
25
|
+
win.item :bring_all_to_front, title: 'Bring All to Front', key: 'o'
|
26
26
|
end
|
27
27
|
main.submenu :help do |help|
|
28
|
-
help.item :help, :
|
28
|
+
help.item :help, title: "#{NSApp.name} Help"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'hotcocoa/application/builder'
|
2
|
+
|
3
|
+
class TestApplicationBuilder < MiniTest::Unit::TestCase
|
4
|
+
include Application
|
5
|
+
|
6
|
+
TEST_DIR = File.join(ENV['TMPDIR'], 'test_app_specification')
|
7
|
+
|
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'
|
11
|
+
|
12
|
+
def setup; FileUtils.mkdir TEST_DIR; end
|
13
|
+
def teardown; FileUtils.rm_rf TEST_DIR; end
|
14
|
+
|
15
|
+
def test_caches_spec
|
16
|
+
spec = Specification.load STOPWATCH
|
17
|
+
builder = Builder.new spec
|
18
|
+
assert_equal spec, builder.spec
|
19
|
+
end
|
20
|
+
|
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"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
require 'hotcocoa/application/specification'
|
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'
|
9
|
+
|
10
|
+
def rescue_spec_error_for &block
|
11
|
+
begin
|
12
|
+
Specification.new &block
|
13
|
+
rescue Specification::Error => e
|
14
|
+
return e
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
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
|
+
def test_spec_requires_a_block
|
27
|
+
error = rescue_spec_error_for # no block given
|
28
|
+
assert_match /must pass a block/, error.message
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_name_is_string_of_given_name
|
32
|
+
['Test', [1,2,3]].each do |name|
|
33
|
+
spec = Specification.new do |s|
|
34
|
+
s.name = name
|
35
|
+
s.identifier = 'com.test.test'
|
36
|
+
end
|
37
|
+
assert_equal name.to_s, spec.name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_name_is_verified
|
42
|
+
exception = rescue_spec_error_for { |_| }
|
43
|
+
assert_match /name is required/, exception.message
|
44
|
+
|
45
|
+
exception = rescue_spec_error_for { |s| s.name = '' }
|
46
|
+
assert_match /cannot be an empty string/, exception.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_name_warns_if_too_long
|
50
|
+
output = capture_io do
|
51
|
+
rescue_spec_error_for { |s| s.name = 'Really long app name' }
|
52
|
+
end
|
53
|
+
assert_match /should be less than 16 characters/, output.last
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_identifier_is_verified
|
57
|
+
exception = rescue_spec_error_for { |s| s.name = 'test' }
|
58
|
+
assert_match /identifier is required/, exception.message
|
59
|
+
|
60
|
+
exception = rescue_spec_error_for do |s|
|
61
|
+
s.name = 'test'
|
62
|
+
s.identifier = ''
|
63
|
+
end
|
64
|
+
assert_match /cannot be an empty string/, exception.message
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_identifier_limits_character_set
|
68
|
+
exception = rescue_spec_error_for do |s|
|
69
|
+
s.name = 'test'
|
70
|
+
s.identifier = ','
|
71
|
+
end
|
72
|
+
assert_match /bundle identifier may only/, exception.message
|
73
|
+
assert_match /You had ","/, exception.message
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_version_defaults_to_1_if_not_set
|
77
|
+
assert_equal '1.0', minimal_spec.version
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_version_is_forced_to_a_string
|
81
|
+
spec = minimal_spec do |s|
|
82
|
+
s.version = 3.1415
|
83
|
+
end
|
84
|
+
assert_equal '3.1415', spec.version
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_short_version_is_empty_by_default
|
88
|
+
assert_nil minimal_spec.short_version
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_short_version_is_forced_to_a_string_if_defined
|
92
|
+
spec = minimal_spec do |s|
|
93
|
+
s.short_version = 3.1415
|
94
|
+
end
|
95
|
+
assert_equal '3.1415', spec.short_version
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_copyright_is_verified
|
99
|
+
assert_nil minimal_spec.copyright
|
100
|
+
|
101
|
+
spec = minimal_spec do |s|
|
102
|
+
s.copyright = Math::PI
|
103
|
+
end
|
104
|
+
assert_equal Math::PI.to_s, spec.copyright
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_type_has_a_default
|
108
|
+
assert_equal 'APPL', minimal_spec.type
|
109
|
+
|
110
|
+
spec = minimal_spec { |s| s.type = 'BNDL' }
|
111
|
+
assert_equal 'BNDL', spec.type
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_type_is_verified
|
115
|
+
error = rescue_spec_error_for do |s|
|
116
|
+
s.name = 'test'
|
117
|
+
s.identifier = 'com.test.test'
|
118
|
+
s.type = 'TOO LONG'
|
119
|
+
end
|
120
|
+
assert_match /bundle type must be exactly 4 characters/, error.message
|
121
|
+
|
122
|
+
error = rescue_spec_error_for do |s|
|
123
|
+
s.name = 'test'
|
124
|
+
s.identifier = 'com.test.test'
|
125
|
+
s.type = 'TOO'
|
126
|
+
end
|
127
|
+
assert_match /bundle type must be exactly 4 characters/, error.message
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_signature_has_a_default
|
131
|
+
assert_equal '????', minimal_spec.signature
|
132
|
+
|
133
|
+
spec = minimal_spec { |s| s.signature = 'girb' }
|
134
|
+
assert_equal 'girb', spec.signature
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_signature_is_verified
|
138
|
+
error = rescue_spec_error_for do |s|
|
139
|
+
s.name = 'test'
|
140
|
+
s.identifier = 'com.test.test'
|
141
|
+
s.signature = 'thingy'
|
142
|
+
end
|
143
|
+
assert_match /bundle signature must be exactly 4 characters/, error.message
|
144
|
+
|
145
|
+
error = rescue_spec_error_for do |s|
|
146
|
+
s.name = 'test'
|
147
|
+
s.identifier = 'com.test.test'
|
148
|
+
s.signature = 'two'
|
149
|
+
end
|
150
|
+
assert_match /bundle signature must be exactly 4 characters/, error.message
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_agent_has_a_default
|
154
|
+
assert_equal false, minimal_spec.agent
|
155
|
+
|
156
|
+
spec = minimal_spec { |s| s.agent = true }
|
157
|
+
assert_equal true, spec.agent
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_agent_is_verified
|
161
|
+
spec = minimal_spec { |s| s.agent = 'cake' }
|
162
|
+
assert_equal true, spec.agent
|
163
|
+
|
164
|
+
spec = minimal_spec { |s| s.agent = nil }
|
165
|
+
assert_equal false, spec.agent
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_sources_resources_and_data_models_are_initialized_to_an_empty_array_if_not_provided
|
169
|
+
spec = minimal_spec
|
170
|
+
assert_empty spec.sources
|
171
|
+
assert_empty spec.resources
|
172
|
+
assert_empty spec.data_models
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_stdlib_attribute_true_by_default
|
176
|
+
spec = minimal_spec
|
177
|
+
assert_equal true, spec.stdlib
|
178
|
+
|
179
|
+
spec = minimal_spec { |s| s.stdlib = false }
|
180
|
+
assert_equal false, spec.stdlib
|
181
|
+
|
182
|
+
libs = ['base64', 'matrix']
|
183
|
+
spec = minimal_spec { |s| s.stdlib = libs }
|
184
|
+
assert_equal libs, spec.stdlib
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_compile_is_true_by_default
|
188
|
+
spec = minimal_spec
|
189
|
+
assert spec.compile?
|
190
|
+
assert spec.compile
|
191
|
+
|
192
|
+
spec = minimal_spec { |s| s.compile = false }
|
193
|
+
refute spec.compile?
|
194
|
+
refute spec.compile
|
195
|
+
end
|
196
|
+
|
197
|
+
# test is kind of annoying since it tests code that does
|
198
|
+
# not belong to us
|
199
|
+
def test_add_dependency_adds_dependency_to_list
|
200
|
+
spec = minimal_spec do |s|
|
201
|
+
s.add_runtime_dependency 'jiraSOAP'
|
202
|
+
s.add_dependency 'nokogiri'
|
203
|
+
s.add_dependency 'mail', '2.3.0'
|
204
|
+
s.add_dependency 'activesupport', ['3.0.10']
|
205
|
+
s.add_dependency 'meme_generator', '~> 1.9.0'
|
206
|
+
s.add_dependency 'Salut', '>= 0', '< 2.0.0'
|
207
|
+
end
|
208
|
+
|
209
|
+
assert spec.gems.all? { |s| s.kind_of? Gem::Dependency }
|
210
|
+
|
211
|
+
assert_includes spec.gems,
|
212
|
+
Gem::Dependency.new('jiraSOAP', Gem::Requirement.default, :runtime)
|
213
|
+
|
214
|
+
assert_includes spec.gems,
|
215
|
+
Gem::Dependency.new('nokogiri', Gem::Requirement.default, :runtime)
|
216
|
+
|
217
|
+
assert_includes spec.gems,
|
218
|
+
Gem::Dependency.new('mail', '2.3.0', :runtime)
|
219
|
+
|
220
|
+
assert_includes spec.gems,
|
221
|
+
Gem::Dependency.new('activesupport', '3.0.10', :runtime)
|
222
|
+
|
223
|
+
assert_includes spec.gems,
|
224
|
+
Gem::Dependency.new('meme_generator', '~> 1.9.0', :runtime)
|
225
|
+
|
226
|
+
assert_includes spec.gems,
|
227
|
+
Gem::Dependency.new('Salut', '>= 0', '< 2.0.0', :runtime)
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_embed_bs_has_a_default
|
231
|
+
spec = minimal_spec
|
232
|
+
assert_equal false, spec.embed_bs?
|
233
|
+
assert_equal false, spec.embed_bs
|
234
|
+
|
235
|
+
spec = minimal_spec { |s| s.embed_bs = true }
|
236
|
+
assert_equal true, spec.embed_bs?
|
237
|
+
assert_equal true, spec.embed_bs
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_overwirte_attribute_is_false_by_default
|
241
|
+
spec = minimal_spec
|
242
|
+
refute spec.overwrite?
|
243
|
+
|
244
|
+
spec = minimal_spec { |s| s.overwrite = true }
|
245
|
+
assert spec.overwrite?
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_icon_exists?
|
249
|
+
refute minimal_spec.icon_exists?
|
250
|
+
|
251
|
+
spec = minimal_spec { |s| s.icon = '/thing.png' }
|
252
|
+
refute spec.icon_exists?
|
253
|
+
|
254
|
+
spec = minimal_spec do |s|
|
255
|
+
s.icon = '/Applications/Calculator.app/Contents/Resources/Calculator.icns'
|
256
|
+
end
|
257
|
+
assert spec.icon_exists?
|
258
|
+
end
|
259
|
+
|
260
|
+
# doubles as an integration test
|
261
|
+
def test_load_evaluates_files_properly
|
262
|
+
spec = Application::Specification.load HOTCONSOLE
|
263
|
+
assert_equal 'HotConsole', spec.name
|
264
|
+
assert_equal 'com.vincentisambart.HotConsole', spec.identifier
|
265
|
+
assert_equal '1.0', spec.version
|
266
|
+
assert_equal Dir.glob('lib/**/*.rb'), spec.sources
|
267
|
+
assert_equal [], spec.resources
|
268
|
+
assert_equal 'girb', spec.signature
|
269
|
+
|
270
|
+
spec = Application::Specification.load STOPWATCH
|
271
|
+
assert_equal 'Stopwatch', spec.name
|
272
|
+
assert_equal 'nz.co.kearse.stopwatch', spec.identifier
|
273
|
+
assert_equal Dir.glob('{lib,hotcocoa}*/**/*.rb'), spec.sources
|
274
|
+
assert_equal [], spec.resources
|
275
|
+
assert_equal true, spec.agent
|
276
|
+
assert_equal true, spec.overwrite
|
277
|
+
assert_equal false, spec.stdlib
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class TestKernelFramework < MiniTest::Unit::TestCase
|
2
|
+
|
3
|
+
def test_original_framework_loading_semantics_are_preserved
|
4
|
+
assert framework 'ApplicationServices'
|
5
|
+
refute framework 'Cocoa'
|
6
|
+
|
7
|
+
assert_raises RuntimeError do framework 'MadeUpFrameworkName' end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_loaded_frameworks
|
11
|
+
refute $LOADED_FRAMEWORKS.find { |x| x.match /.framework/ }
|
12
|
+
assert_empty $LOADED_FRAMEWORKS - $LOADED_FRAMEWORKS
|
13
|
+
assert_includes $LOADED_FRAMEWORKS, 'Cocoa'
|
14
|
+
assert_includes $LOADED_FRAMEWORKS, 'AppKit'
|
15
|
+
assert_includes $LOADED_FRAMEWORKS, 'Foundation'
|
16
|
+
|
17
|
+
refute_includes $LOADED_FRAMEWORKS, 'CoreWLAN'
|
18
|
+
framework 'CoreWLAN'
|
19
|
+
assert_includes $LOADED_FRAMEWORKS, 'CoreWLAN'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
class TestKernelToPlist < MiniTest::Unit::TestCase
|
26
|
+
include HotCocoa
|
27
|
+
|
28
|
+
def test_normal_cases_in_xml
|
29
|
+
@format = :xml
|
30
|
+
normal_cases
|
31
|
+
@format = nil
|
32
|
+
normal_cases
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_normal_cases_in_binary
|
36
|
+
@format = :binary
|
37
|
+
normal_cases
|
38
|
+
end
|
39
|
+
|
40
|
+
def normal_cases
|
41
|
+
assert_plist 123
|
42
|
+
assert_plist true
|
43
|
+
assert_plist false
|
44
|
+
assert_plist 'foo'
|
45
|
+
assert_plist 'aiueo'.transform('latin-hiragana')
|
46
|
+
assert_plist :foo, 'foo'
|
47
|
+
assert_plist [1,2,3]
|
48
|
+
assert_plist 'un' => 1, 'deux' => 2
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_raises_error_for_invalid_objects
|
52
|
+
assert_raises Exception do nil.to_plist end
|
53
|
+
assert_raises Exception do Object.new.to_plist end
|
54
|
+
assert_raises Exception do /foo/.to_plist end
|
55
|
+
assert_raises Exception do nil.to_plist(:binary) end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def assert_plist val, expected = val
|
62
|
+
ret = @format ? load_plist(val.to_plist(@format)) : load_plist(val.to_plist)
|
63
|
+
assert_equal expected, ret
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class TestNSMutableAttributedStringExt < MiniTest::Unit::TestCase
|
2
|
+
|
3
|
+
def attrs
|
4
|
+
{
|
5
|
+
NSFontAttributeName => NSFont.toolTipsFontOfSize(10),
|
6
|
+
NSObliquenessAttributeName => 5.0
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
def attr_string value = 'test'
|
11
|
+
string = NSMutableAttributedString.alloc.initWithString value,
|
12
|
+
attributes: attrs
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_with_attributes_makes_new_attributed_string
|
16
|
+
string = NSMutableAttributedString.alloc.initWithString 'test',
|
17
|
+
attributes: attrs
|
18
|
+
refute_same string, string.with_attributes(attrs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_with_attributes_uses_given_attributes
|
22
|
+
string = NSMutableAttributedString.alloc.initWithString 'test'
|
23
|
+
new_string = string.with_attributes attrs
|
24
|
+
assert_equal attrs, new_string.fontAttributesInRange(NSRange.new 0, 4)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_append_another_attributed_string
|
28
|
+
string = attr_string
|
29
|
+
other_string = attr_string ' other'
|
30
|
+
string << other_string
|
31
|
+
assert_equal 'test other', string.string
|
32
|
+
assert_equal attrs, string.fontAttributesInRange(NSRange.new 0, 10)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_append_a_string
|
36
|
+
string = attr_string
|
37
|
+
string << ' string'
|
38
|
+
assert_equal 'test string', string.string
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_addition_makes_new_string
|
42
|
+
string = attr_string
|
43
|
+
new_string = string + string
|
44
|
+
refute_same string, new_string
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_addition_sends_work_to_append
|
48
|
+
string = attr_string
|
49
|
+
NSMutableAttributedString.send :alias_method, :__temp__, :<<
|
50
|
+
NSMutableAttributedString.send :define_method, :<< do |_|
|
51
|
+
@append_called = true
|
52
|
+
end
|
53
|
+
new_string = string + string
|
54
|
+
assert new_string.instance_variable_get(:@append_called), 'append not called'
|
55
|
+
ensure
|
56
|
+
NSMutableAttributedString.send :alias_method, :<<, :__temp__
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_attributes_returns_a_hash_of_attributes_used_on_the_string
|
60
|
+
string = attr_string
|
61
|
+
assert_equal attrs.sort, string.attributes.to_hash.sort
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_replace_range_with_string
|
65
|
+
string = attr_string 'my string'
|
66
|
+
string[0..-1] = 'bwa ha ha'
|
67
|
+
assert_equal 'bwa ha ha', string.string
|
68
|
+
|
69
|
+
string[0...1] = 'm'
|
70
|
+
assert_equal 'mwa ha ha', string.string
|
71
|
+
|
72
|
+
string[0..8] = 'my string'
|
73
|
+
assert_equal 'my string', string.string
|
74
|
+
|
75
|
+
string[0...9] = 'bwa ha ha'
|
76
|
+
assert_equal 'bwa ha ha', string.string
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_replace_range_with_attributed_string
|
80
|
+
string = attr_string 'my string'
|
81
|
+
string[0..-1] = attr_string 'bwa ha ha'
|
82
|
+
assert_equal 'bwa ha ha', string.string
|
83
|
+
assert_equal attrs, string.fontAttributesInRange(NSRange.new 0, 9)
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class TestNSStringExt < MiniTest::Unit::TestCase
|
2
|
+
|
3
|
+
def test_convert_from_camelcase_to_underscore
|
4
|
+
assert 'SampleCamelCasedWord'.underscore, 'sample_camel_cased_word'
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_convert_from_underscore_to_camelcase
|
8
|
+
assert 'sample_camel_cased_word'.camel_case, 'SampleCamelCasedWord'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_convert_to_attributed_string
|
12
|
+
attrs = {
|
13
|
+
NSFontAttributeName => NSFont.toolTipsFontOfSize(10),
|
14
|
+
NSObliquenessAttributeName => 5.0
|
15
|
+
}
|
16
|
+
string = 'my test string'.with_attributes attrs
|
17
|
+
assert_equal attrs, string.fontAttributesInRange(NSRange.new 0, 10)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|