rb-appscript 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/CHANGES +243 -0
  2. data/LICENSE +1 -0
  3. data/README +42 -0
  4. data/TODO +31 -0
  5. data/doc/aem-manual/01_introduction.html +48 -0
  6. data/doc/aem-manual/02_apioverview.html +89 -0
  7. data/doc/aem-manual/03_packingandunpackingdata.html +98 -0
  8. data/doc/aem-manual/04_references.html +401 -0
  9. data/doc/aem-manual/05_targettingapplications.html +133 -0
  10. data/doc/aem-manual/06_buildingandsendingevents.html +175 -0
  11. data/doc/aem-manual/07_findapp.html +54 -0
  12. data/doc/aem-manual/08_examples.html +85 -0
  13. data/doc/aem-manual/09_notes.html +41 -0
  14. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  15. data/doc/aem-manual/full.css +21 -0
  16. data/doc/aem-manual/index.html +43 -0
  17. data/doc/appscript-manual/01_introduction.html +82 -0
  18. data/doc/appscript-manual/02_aboutappscripting.html +244 -0
  19. data/doc/appscript-manual/03_quicktutorial.html +154 -0
  20. data/doc/appscript-manual/04_gettinghelp.html +101 -0
  21. data/doc/appscript-manual/05_keywordconversion.html +91 -0
  22. data/doc/appscript-manual/06_classesandenums.html +174 -0
  23. data/doc/appscript-manual/07_applicationobjects.html +181 -0
  24. data/doc/appscript-manual/08_realvsgenericreferences.html +86 -0
  25. data/doc/appscript-manual/09_referenceforms.html +232 -0
  26. data/doc/appscript-manual/10_referenceexamples.html +142 -0
  27. data/doc/appscript-manual/11_applicationcommands.html +204 -0
  28. data/doc/appscript-manual/12_commandexamples.html +129 -0
  29. data/doc/appscript-manual/13_performanceissues.html +115 -0
  30. data/doc/appscript-manual/14_problemapps.html +193 -0
  31. data/doc/appscript-manual/15_notes.html +84 -0
  32. data/doc/appscript-manual/application_architecture.gif +0 -0
  33. data/doc/appscript-manual/application_architecture2.gif +0 -0
  34. data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
  35. data/doc/appscript-manual/full.css +21 -0
  36. data/doc/appscript-manual/index.html +49 -0
  37. data/doc/appscript-manual/relationships_example.gif +0 -0
  38. data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
  39. data/doc/index.html +30 -0
  40. data/doc/mactypes-manual/index.html +216 -0
  41. data/doc/osax-manual/index.html +169 -0
  42. data/extconf.rb +54 -0
  43. data/misc/adobeunittypes.rb +14 -0
  44. data/misc/dump.rb +72 -0
  45. data/rb-appscript.gemspec +20 -0
  46. data/sample/AB_list_people_with_emails.rb +8 -0
  47. data/sample/Create_daily_iCal_todos.rb +72 -0
  48. data/sample/Hello_world.rb +9 -0
  49. data/sample/List_iTunes_playlist_names.rb +7 -0
  50. data/sample/Make_Mail_message.rb +29 -0
  51. data/sample/Open_file_in_TextEdit.rb +9 -0
  52. data/sample/Organize_Mail_messages.rb +57 -0
  53. data/sample/Print_folder_tree.rb +12 -0
  54. data/sample/Select_all_HTML_files.rb +8 -0
  55. data/sample/Set_iChat_status.rb +20 -0
  56. data/sample/Simple_Finder_GUI_Scripting.rb +14 -0
  57. data/sample/Stagger_Finder_windows.rb +21 -0
  58. data/sample/TextEdit_demo.rb +126 -0
  59. data/sample/iTunes_top40_to_html.rb +64 -0
  60. data/src/lib/_aem/aemreference.rb +1006 -0
  61. data/src/lib/_aem/codecs.rb +617 -0
  62. data/src/lib/_aem/connect.rb +100 -0
  63. data/src/lib/_aem/findapp.rb +83 -0
  64. data/src/lib/_aem/mactypes.rb +228 -0
  65. data/src/lib/_aem/send.rb +257 -0
  66. data/src/lib/_aem/typewrappers.rb +57 -0
  67. data/src/lib/_appscript/defaultterminology.rb +245 -0
  68. data/src/lib/_appscript/referencerenderer.rb +132 -0
  69. data/src/lib/_appscript/reservedkeywords.rb +107 -0
  70. data/src/lib/_appscript/terminology.rb +314 -0
  71. data/src/lib/aem.rb +216 -0
  72. data/src/lib/appscript.rb +830 -0
  73. data/src/lib/kae.rb +1484 -0
  74. data/src/lib/osax.rb +171 -0
  75. data/src/rbae.c +766 -0
  76. data/test/README +1 -0
  77. data/test/test_aemreference.rb +112 -0
  78. data/test/test_appscriptreference.rb +102 -0
  79. data/test/test_codecs.rb +159 -0
  80. data/test/test_findapp.rb +24 -0
  81. data/test/test_mactypes.rb +67 -0
  82. data/test/testall.sh +9 -0
  83. metadata +143 -0
data/test/README ADDED
@@ -0,0 +1 @@
1
+ Some of the code in these tests may not yet be 100% portable (hardcoded paths, etc) so may currently fail for some users, although they have passed for Ruby 1.8.x on OS X 10.3.9 and OS X 10.4.x (PPC & i386).
@@ -0,0 +1,112 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require "_aem/aemreference"
5
+ require "_aem/typewrappers"
6
+ require "_aem/codecs"
7
+
8
+
9
+ class TC_AEMReferences < Test::Unit::TestCase
10
+
11
+ def test_reference_forms
12
+ [
13
+ [AEMReference::App.property('ctxt'), 'AEM.app.property("ctxt")', nil],
14
+
15
+ [AEMReference::App.elements('docu'), 'AEM.app.elements("docu")', nil],
16
+
17
+ [AEMReference::App.elements('docu').by_index(1),
18
+ 'AEM.app.elements("docu").by_index(1)', nil],
19
+ [AEMReference::App.elements('docu').by_name('foo'),
20
+ 'AEM.app.elements("docu").by_name("foo")', nil],
21
+ [AEMReference::App.elements('docu').by_id(300),
22
+ 'AEM.app.elements("docu").by_id(300)', nil],
23
+
24
+ [AEMReference::App.elements('docu').next('docu'),
25
+ 'AEM.app.elements("docu").next("docu")', nil],
26
+ [AEMReference::App.elements('docu').previous('docu'),
27
+ 'AEM.app.elements("docu").previous("docu")', nil],
28
+
29
+ [AEMReference::App.elements('docu').first, 'AEM.app.elements("docu").first', nil],
30
+ [AEMReference::App.elements('docu').middle, 'AEM.app.elements("docu").middle', nil],
31
+ [AEMReference::App.elements('docu').last, 'AEM.app.elements("docu").last', nil],
32
+ [AEMReference::App.elements('docu').any, 'AEM.app.elements("docu").any', nil],
33
+
34
+ [AEMReference::Con.elements("docu").by_index(3), 'AEM.con.elements("docu").by_index(3)', nil],
35
+
36
+ [AEMReference::App.elements('docu').by_range(
37
+ AEMReference::Con.elements('docu').by_index(3),
38
+ AEMReference::Con.elements('docu').by_name('foo')),
39
+ 'AEM.app.elements("docu").by_range(' +
40
+ 'AEM.con.elements("docu").by_index(3), ' +
41
+ 'AEM.con.elements("docu").by_name("foo"))', nil],
42
+
43
+
44
+ [AEMReference::Its.property('name').eq('foo').and(AEMReference::Its.elements('cwor').eq([])),
45
+ 'AEM.its.property("name").eq("foo").and(AEM.its.elements("cwor").eq([]))', nil],
46
+
47
+ [AEMReference::Its.elements('cwor').ne([]),
48
+ 'AEM.its.elements("cwor").ne([])',
49
+ AEMReference::Its.elements("cwor").eq([]).not], # i.e. there isn't a KAENotEqual operator, so not-equal tests are actually packed as an equal test followed by not test
50
+
51
+ [AEMReference::Its.elements('cwor').eq(nil), 'AEM.its.elements("cwor").eq(nil)', nil],
52
+ [AEMReference::Its.elements('cwor').property('leng').gt(0),
53
+ 'AEM.its.elements("cwor").property("leng").gt(0)', nil],
54
+ [AEMReference::Its.elements('cwor').le(''), 'AEM.its.elements("cwor").le("")', nil],
55
+ [AEMReference::Its.elements('cwor').starts_with('foo').not,
56
+ 'AEM.its.elements("cwor").starts_with("foo").not', nil],
57
+
58
+
59
+ [AEMReference::Its.elements('cwor').contains('foo'), 'AEM.its.elements("cwor").contains("foo")', nil],
60
+ [AEMReference::Its.elements('cwor').is_in('foo'), 'AEM.its.elements("cwor").is_in("foo")', nil],
61
+
62
+ [AEMReference::App.elements('docu').by_filter(AEMReference::Its.property('size').ge(42)),
63
+ 'AEM.app.elements("docu").by_filter(AEM.its.property("size").ge(42))', nil],
64
+
65
+ [AEMReference::App.elements('docu').by_index(1).property('ctxt') \
66
+ .elements('cpar').elements('cha ').by_range(
67
+ AEMReference::Con.elements('cha ').by_index(3),
68
+ AEMReference::Con.elements('cha ').by_index(55)
69
+ ).next('cha ').after,
70
+ 'AEM.app.elements("docu").by_index(1).property("ctxt").elements("cpar").elements("cha ")' +
71
+ '.by_range(AEM.con.elements("cha ").by_index(3), AEM.con.elements("cha ").by_index(55))' +
72
+ '.next("cha ").after', nil],
73
+
74
+ [AEMReference::Its.property('pnam').ne('foo').and(AEMReference::Its.elements('cfol').eq([])).not,
75
+ 'AEM.its.property("pnam").ne("foo").and(AEM.its.elements("cfol").eq([])).not',
76
+ AEMReference::Its.property('pnam').eq('foo').not.and(AEMReference::Its.elements('cfol').eq([])).not],
77
+
78
+ [AEMReference::App.elements('docu').start, 'AEM.app.elements("docu").start', nil],
79
+ [AEMReference::App.elements('docu').end, 'AEM.app.elements("docu").end', nil],
80
+ [AEMReference::App.elements('docu').by_index(3).before, 'AEM.app.elements("docu").by_index(3).before', nil],
81
+ [AEMReference::App.elements('docu').by_name('foo').after, 'AEM.app.elements("docu").by_name("foo").after', nil],
82
+
83
+ ].each do |val, res, unpacked_version|
84
+ begin
85
+ assert_equal(res, val.to_s)
86
+ d = DefaultCodecs.pack(val)
87
+ val = unpacked_version ? unpacked_version : val
88
+ val2 = DefaultCodecs.unpack(d)
89
+ assert_equal(val, val2)
90
+ val2 = DefaultCodecs.unpack(d)
91
+ assert_block { val.eql?(val2) }
92
+ val2 = DefaultCodecs.unpack(d)
93
+ assert_equal(val2, val)
94
+ val2 = DefaultCodecs.unpack(d)
95
+ assert_block { val2.eql?(val) }
96
+ rescue
97
+ puts 'EXPECTED: ' + res
98
+ raise
99
+ end
100
+ end
101
+ assert_not_equal(AEMReference::App.property('ctxt').property('ctxt'), AEMReference::Con.property('ctxt').property('ctxt'))
102
+ assert_not_equal(AEMReference::App.property('foob').property('ctxt'), AEMReference::App.property('ctxt').property('ctxt'))
103
+ assert_not_equal(AEMReference::App.elements('ctxt').property('ctxt'), AEMReference::App.property('ctxt').property('ctxt'))
104
+ assert_not_equal(AEMReference::App.elements('ctxt').property('ctxt'), 333)
105
+ assert_not_equal(333, AEMReference::App.property('ctxt').property('ctxt'))
106
+ # by-range and by-filter references do basic type checking to ensure a reference is given
107
+ assert_raises(TypeError) { AEMReference::App.elements('docu').by_range(1, 2) }
108
+ assert_raises(TypeError) { AEMReference::App.elements('docu').by_filter(1) }
109
+
110
+ end
111
+ end
112
+
@@ -0,0 +1,102 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require "appscript"
5
+
6
+
7
+ class TC_AppscriptReferences < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @te = AS.app('TextEdit')
11
+ @s = @te.to_s
12
+ end
13
+
14
+ def test_reference_forms
15
+ [
16
+ [@te.text, @s+'.text', nil],
17
+
18
+ [@te.documents, @s+'.documents', nil],
19
+
20
+ [@te.documents[1],
21
+ @s+'.documents[1]', nil],
22
+ [@te.documents['foo'],
23
+ @s+'.documents["foo"]', nil],
24
+ [@te.documents.ID(300),
25
+ @s+'.documents.ID(300)', nil],
26
+
27
+ [@te.documents.next(:document),
28
+ @s+'.documents.next(:document)', nil],
29
+ [@te.documents.previous(:document),
30
+ @s+'.documents.previous(:document)', nil],
31
+
32
+ [@te.documents.first, @s+'.documents.first', nil],
33
+ [@te.documents.middle, @s+'.documents.middle', nil],
34
+ [@te.documents.last, @s+'.documents.last', nil],
35
+ [@te.documents.any, @s+'.documents.any', nil],
36
+
37
+ [AS.con.documents[3], 'AS.con.documents[3]', nil],
38
+
39
+ [@te.documents[
40
+ AS.con.documents[3],
41
+ AS.con.documents['foo']],
42
+ @s+'.documents[' +
43
+ 'AS.con.documents[3], ' +
44
+ 'AS.con.documents["foo"]]', nil],
45
+
46
+
47
+ [AS.its.name.eq('foo').and(AS.its.words.eq([])),
48
+ 'AS.its.name.eq("foo").and(AS.its.words.eq([]))', nil],
49
+
50
+ [AS.its.words.ne([]),
51
+ 'AS.its.words.ne([])',
52
+ AS.its.words.eq([]).not], # i.e. there isn't a KAENotEqual operator, so not-equal tests are actually packed as an equal test followed by not test
53
+
54
+ [AS.its.words.eq(nil), 'AS.its.words.eq(nil)', nil],
55
+ [AS.its.words.size.gt(0),
56
+ 'AS.its.words.size.gt(0)', nil],
57
+ [AS.its.words.le(''), 'AS.its.words.le("")', nil],
58
+ [AS.its.words.starts_with('foo').not,
59
+ 'AS.its.words.starts_with("foo").not', nil],
60
+
61
+
62
+ [AS.its.words.contains('foo'), 'AS.its.words.contains("foo")', nil],
63
+ [AS.its.words.is_in('foo'), 'AS.its.words.is_in("foo")', nil],
64
+
65
+ [@te.documents[AS.its.size.ge(42)],
66
+ @s+'.documents[AS.its.size.ge(42)]', nil],
67
+
68
+ [@te.documents[1, 'foo'],
69
+ @s+'.documents[AS.con.documents[1], AS.con.documents["foo"]]',
70
+ @te.documents[AS.con.documents[1], AS.con.documents['foo']]],
71
+
72
+ [@te.documents[1].text \
73
+ .paragraphs.characters[
74
+ AS.con.characters[3],
75
+ AS.con.characters[55]
76
+ ].next(:character).after,
77
+ @s+'.documents[1].text.paragraphs.characters' +
78
+ '[AS.con.characters[3], AS.con.characters[55]]' +
79
+ '.next(:character).after', nil],
80
+
81
+ [AS.its.name.ne('foo').and(AS.its.words.eq([])).not,
82
+ 'AS.its.name.ne("foo").and(AS.its.words.eq([])).not',
83
+ AS.its.name.eq('foo').not.and(AS.its.words.eq([])).not],
84
+
85
+ [@te.documents.start, @s+'.documents.start', nil],
86
+ [@te.documents.end, @s+'.documents.end', nil],
87
+ [@te.documents[3].before, @s+'.documents[3].before', nil],
88
+ [@te.documents['foo'].after, @s+'.documents["foo"].after', nil],
89
+
90
+ ].each do |val, res, unpacked_version|
91
+ assert_equal(res, val.to_s)
92
+ d = @te.AS_app_data.pack(val)
93
+ val = unpacked_version ? unpacked_version : val
94
+ val2 = @te.AS_app_data.unpack(d)
95
+ if val.class == @te.AS_app_data.unpack(d).class # note: AS::Reference and AS::GenericReference currently aren't comparable with each other, so the next test would always fail for those
96
+ assert_equal(val, val2)
97
+ assert_block { val.eql?(val2) }
98
+ end
99
+ end
100
+ end
101
+ end
102
+
@@ -0,0 +1,159 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require 'aem'
5
+ require 'kae'
6
+ require 'ae'
7
+
8
+ def num(s)
9
+ if [1].pack('s') == "\001\000" # host system is i386
10
+ s.reverse
11
+ else
12
+ s
13
+ end
14
+ end
15
+
16
+ def ut16(s)
17
+ if [1].pack('s') == "\001\000" # host system is i386
18
+ i = 0
19
+ s2 = ''
20
+ (s.length / 2).times do
21
+ s2 += s[i, 2].reverse
22
+ i+=2
23
+ end
24
+ s2
25
+ else
26
+ s
27
+ end
28
+ end
29
+
30
+
31
+
32
+
33
+ class TC_Codecs < Test::Unit::TestCase
34
+
35
+ def setup
36
+ @c = AEM::Codecs.new
37
+ end
38
+
39
+ def test_nil
40
+ d = @c.pack(nil)
41
+ assert_equal(KAE::TypeNull, d.type)
42
+ assert_equal('', d.data)
43
+ assert_nil(@c.unpack(d))
44
+ end
45
+
46
+ def test_bool
47
+ [
48
+ [true, KAE::TypeTrue],
49
+ [false, KAE::TypeFalse]
50
+ ].each do |val, type|
51
+ d = @c.pack(val)
52
+ assert_equal(type, d.type)
53
+ assert_equal('', d.data)
54
+ assert_equal(val, @c.unpack(d))
55
+ end
56
+ assert_equal(true, @c.unpack(AE::AEDesc.new(KAE::TypeBoolean, "\xfe")))
57
+ assert_equal(true, @c.unpack(AE::AEDesc.new(KAE::TypeTrue, '')))
58
+ assert_equal(false, @c.unpack(AE::AEDesc.new(KAE::TypeFalse, '')))
59
+ end
60
+
61
+ def test_num
62
+ [ # (mostly testing at threshold points where Codecs switches types when packing integers)
63
+ [0, "\x00\x00\x00\x00", KAE::TypeInteger],
64
+ [2, "\x00\x00\x00\x02", KAE::TypeInteger],
65
+ [-9, "\xff\xff\xff\xf7", KAE::TypeInteger],
66
+ [2**31-1, "\x7f\xff\xff\xff", KAE::TypeInteger],
67
+ [-2**31, "\x80\x00\x00\x00", KAE::TypeInteger],
68
+ [2**31, "\x00\x00\x00\x00\x80\x00\x00\x00", KAE::TypeSInt64],
69
+ [2**32-1, "\x00\x00\x00\x00\xff\xff\xff\xff", KAE::TypeSInt64],
70
+ [2**32, "\x00\x00\x00\x01\x00\x00\x00\x00", KAE::TypeSInt64],
71
+ [-2**32, "\xff\xff\xff\xff\x00\x00\x00\x00", KAE::TypeSInt64],
72
+ [2**63-1, "\x7f\xff\xff\xff\xff\xff\xff\xff", KAE::TypeSInt64],
73
+ [-2**63, "\x80\x00\x00\x00\x00\x00\x00\x00", KAE::TypeSInt64],
74
+ [-2**63+1, "\x80\x00\x00\x00\x00\x00\x00\x01", KAE::TypeSInt64],
75
+ [2**63, "C\xe0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
76
+ [-2**63-1, "\xc3\xe0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
77
+ [0.1, "?\xb9\x99\x99\x99\x99\x99\x9a", KAE::TypeFloat],
78
+ [-0.9e-9, "\xbe\x0e\xec{\xd5\x12\xb5r", KAE::TypeFloat],
79
+ [2**300, "R\xb0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
80
+ ].each do |val, data, type|
81
+ data = num(data)
82
+ d = @c.pack(val)
83
+ assert_equal(type, d.type)
84
+ assert_equal(data, d.data)
85
+ assert_equal(val, @c.unpack(d))
86
+ end
87
+ end
88
+
89
+ def test_str
90
+ [
91
+ # note: aem has to pack UTF8 data as typeUnicodeText (UTF16) as stupid apps expect that type and will error on typeUTF8Text instead of just asking AEM to coerce it to the desired type in advance.
92
+ # note: UTF16 BOM must be omitted when packing UTF16 data into typeUnicodeText AEDescs, as a BOM will upset stupid apps like iTunes 7 that don't recognise it as a BOM and treat it as character data instead
93
+ ['', ''],
94
+ ['hello', "\000h\000e\000l\000l\000o"],
95
+ ["\xc6\x92\xe2\x88\x82\xc2\xae\xd4\xb7\xd5\x96\xd4\xb9\xe0\xa8\x89\xe3\x82\xa2\xe3\x84\xbb",
96
+ "\x01\x92\"\x02\x00\xae\x057\x05V\x059\n\t0\xa21;"],
97
+ ].each do |val, data, type|
98
+ data = ut16(data)
99
+ d = @c.pack(val)
100
+ assert_equal(KAE::TypeUnicodeText, d.type)
101
+ assert_equal(data, d.data)
102
+ assert_equal(val, @c.unpack(d))
103
+ end
104
+ assert_raises(TypeError) { @c.pack("\x88") } # non-valid UTF8 strings should raise error when coercing from typeUTF8Text to typeUnicodeText
105
+ end
106
+
107
+ def test_date
108
+ # note: not testing on ST-DST boundaries; this is known to have out-by-an-hour problems due to LongDateTime type being crap
109
+ [
110
+ [Time.local(2005, 12, 11, 15, 40, 43), "\x00\x00\x00\x00\xbf\xc1\xf8\xfb"],
111
+ [Time.local(2005, 5, 1, 6, 51, 7), "\x00\x00\x00\x00\xbe\x9a\x2c\xdb"],
112
+ ].each do |t, data|
113
+ data = num(data)
114
+ d = @c.pack(t)
115
+ assert_equal(KAE::TypeLongDateTime, d.type)
116
+ assert_equal(data, d.data)
117
+ assert_equal(t, @c.unpack(AE::AEDesc.new(KAE::TypeLongDateTime, data)))
118
+ end
119
+ end
120
+
121
+ def test_file
122
+ path = '/Applications/TextEdit.app/'
123
+ d = @c.pack(MacTypes::Alias.path(path))
124
+ assert_equal(path, @c.unpack(d).to_s)
125
+
126
+ path = '/Applications/TextEdit.app'
127
+ d = @c.pack(MacTypes::FileURL.path(path))
128
+ assert_equal(path, @c.unpack(d).to_s)
129
+ end
130
+
131
+ def test_typewrappers
132
+ [
133
+ AEM::AEType.new("docu"),
134
+ AEM::AEEnum.new('yes '),
135
+ AEM::AEProp.new('pnam'),
136
+ AEM::AEKey.new('ABCD'),
137
+ ].each do |val|
138
+ d = @c.pack(val)
139
+ val2 = @c.unpack(d)
140
+ assert_equal(val, val2)
141
+ assert_block { val.eql?(val2) }
142
+ val2 = @c.unpack(d)
143
+ assert_equal(val2, val)
144
+ assert_block { val2.eql?(val) }
145
+ end
146
+ assert_raises(ArgumentError) { AEM::AEType.new(3) }
147
+ assert_raises(ArgumentError) { AEM::AEType.new("docum") }
148
+ end
149
+
150
+ def test_list
151
+ end
152
+
153
+ def test_hash
154
+ val = {'foo' => 1, AEM::AEType.new('foob') => 2, AEM::AEProp.new('barr') => 3} # TO DO: also need to test appscript codecs (in separate test) to check String, AEType and Symbol keys all pack and unpack correctly
155
+ expected_val = {'foo' => 1, AEM::AEType.new('foob') => 2, AEM::AEType.new('barr') => 3} # note that four-char-code keys are always unpacked as AEType
156
+ d = @c.pack(val)
157
+ assert_equal(expected_val, @c.unpack(d))
158
+ end
159
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require "_aem/findapp"
5
+
6
+
7
+ class TC_FindApp < Test::Unit::TestCase
8
+
9
+ def test_find
10
+ [
11
+ ['/Applications/iCal.app', '/Applications/iCal.app'],
12
+ ['ical.app', '/Applications/iCal.app'],
13
+ ['ICAL', '/Applications/iCal.app'],
14
+ ].each do |val, res|
15
+ assert_equal(res, FindApp.by_name(val))
16
+ end
17
+ assert_equal('/Applications/TextEdit.app', FindApp.by_creator('ttxt'))
18
+ assert_equal('/System/Library/CoreServices/Finder.app', FindApp.by_id('com.apple.finder'))
19
+ assert_raises(FindApp::ApplicationNotFoundError) { FindApp.by_name('NON-EXISTENT-APP') }
20
+
21
+ # assert_equal("/Users/has/\306\222\303\270u\314\210.app", FindApp.by_name("\306\222\303\270u\314\210.app")) # utf8 paths work ok
22
+ end
23
+ end
24
+
@@ -0,0 +1,67 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require "_aem/mactypes"
5
+
6
+
7
+ class TC_MacTypes < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @path1 = `mktemp -t codecs-test`.chomp
11
+ dir, fname = File.split(@path1)
12
+ @path2 = File.join(dir, 'moved-' + fname)
13
+ # puts "path: #{@path1}" # e.g. /tmp/codecs-test.HWr1EnE3
14
+ end
15
+
16
+ def test_alias
17
+ # make alias
18
+ f = MacTypes::Alias.path(@path1)
19
+
20
+
21
+ assert_equal(MacTypes::Alias.path(@path1), f)
22
+
23
+ # get path
24
+ # note that initial /tmp/codecs-test... path will automatically change to /private/tmp/codecs-test...
25
+ p1 = '/private'+@path1
26
+ p2 = '/private'+@path2
27
+
28
+ assert_equal("MacTypes::Alias.path(#{p1.inspect})", f.inspect)
29
+
30
+ #puts "alias path 1: #{f}" # e.g. /private/tmp/codecs-test.HWr1EnE3
31
+ assert_equal(p1, f.to_s)
32
+
33
+ # get desc
34
+ #puts f.desc.type, f.desc.data # alis, [binary data]
35
+ assert_equal('alis', f.desc.type)
36
+
37
+
38
+ # check alias keeps track of moved file
39
+ `mv #{@path1} #{@path2}`
40
+ # puts "alias path 2: #{f}" # /private/tmp/moved-codecs-test.HWr1EnE3
41
+ assert_equal(p2, f.to_s)
42
+
43
+ assert_equal("MacTypes::Alias.path(#{p2.inspect})", f.inspect)
44
+
45
+ # check a FileNotFoundError is raised if getting path/FileURL for a filesystem object that no longer exists
46
+ `rm #{@path2}`
47
+ assert_raises(MacTypes::FileNotFoundError) { f.to_s } # File not found.
48
+ assert_raises(MacTypes::FileNotFoundError) { f.to_file_url } # File not found.
49
+ end
50
+
51
+
52
+ def test_file_url
53
+
54
+ g = MacTypes::FileURL.path('/non/existent path')
55
+
56
+ assert_equal('/non/existent path', g.to_s)
57
+
58
+ assert_equal('furl', g.desc.type)
59
+ assert_equal('file://localhost/non/existent%20path', g.desc.data)
60
+
61
+ assert_equal('MacTypes::FileURL.path("/non/existent path")', g.to_file_url.inspect)
62
+
63
+ # check a not-found error is raised if getting Alias for a filesystem object that doesn't exist
64
+ assert_raises(MacTypes::FileNotFoundError) { g.to_alias } # File "/non/existent path" not found.
65
+
66
+ end
67
+ end
data/test/testall.sh ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ for f in `ls | grep test_`;
4
+ do
5
+ /usr/local/bin/ruby $f
6
+ echo
7
+ echo
8
+ done
9
+
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: rb-appscript
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.2.0
7
+ date: 2006-11-21 00:00:00 +00:00
8
+ summary: Ruby appscript (rb-appscript) is a high-level, user-friendly Apple event bridge that allows you to control scriptable Mac OS X applications using ordinary Ruby scripts.
9
+ require_paths:
10
+ - lib
11
+ email:
12
+ homepage: http://rb-appscript.rubyforge.org/
13
+ rubyforge_project: rb-appscript
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.8"
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - HAS
31
+ files:
32
+ - CHANGES
33
+ - doc
34
+ - extconf.rb
35
+ - LICENSE
36
+ - misc
37
+ - rb-appscript.gemspec
38
+ - README
39
+ - sample
40
+ - src
41
+ - test
42
+ - TODO
43
+ - doc/aem-manual
44
+ - doc/appscript-manual
45
+ - doc/index.html
46
+ - doc/mactypes-manual
47
+ - doc/osax-manual
48
+ - doc/aem-manual/01_introduction.html
49
+ - doc/aem-manual/02_apioverview.html
50
+ - doc/aem-manual/03_packingandunpackingdata.html
51
+ - doc/aem-manual/04_references.html
52
+ - doc/aem-manual/05_targettingapplications.html
53
+ - doc/aem-manual/06_buildingandsendingevents.html
54
+ - doc/aem-manual/07_findapp.html
55
+ - doc/aem-manual/08_examples.html
56
+ - doc/aem-manual/09_notes.html
57
+ - doc/aem-manual/aemreferenceinheritance.gif
58
+ - doc/aem-manual/full.css
59
+ - doc/aem-manual/index.html
60
+ - doc/appscript-manual/01_introduction.html
61
+ - doc/appscript-manual/02_aboutappscripting.html
62
+ - doc/appscript-manual/03_quicktutorial.html
63
+ - doc/appscript-manual/04_gettinghelp.html
64
+ - doc/appscript-manual/05_keywordconversion.html
65
+ - doc/appscript-manual/06_classesandenums.html
66
+ - doc/appscript-manual/07_applicationobjects.html
67
+ - doc/appscript-manual/08_realvsgenericreferences.html
68
+ - doc/appscript-manual/09_referenceforms.html
69
+ - doc/appscript-manual/10_referenceexamples.html
70
+ - doc/appscript-manual/11_applicationcommands.html
71
+ - doc/appscript-manual/12_commandexamples.html
72
+ - doc/appscript-manual/13_performanceissues.html
73
+ - doc/appscript-manual/14_problemapps.html
74
+ - doc/appscript-manual/15_notes.html
75
+ - doc/appscript-manual/application_architecture.gif
76
+ - doc/appscript-manual/application_architecture2.gif
77
+ - doc/appscript-manual/finder_to_textedit_event.gif
78
+ - doc/appscript-manual/full.css
79
+ - doc/appscript-manual/index.html
80
+ - doc/appscript-manual/relationships_example.gif
81
+ - doc/appscript-manual/ruby_to_itunes_event.gif
82
+ - doc/mactypes-manual/index.html
83
+ - doc/osax-manual/index.html
84
+ - misc/adobeunittypes.rb
85
+ - misc/dump.rb
86
+ - sample/AB_list_people_with_emails.rb
87
+ - sample/Create_daily_iCal_todos.rb
88
+ - sample/Hello_world.rb
89
+ - sample/iTunes_top40_to_html.rb
90
+ - sample/List_iTunes_playlist_names.rb
91
+ - sample/Make_Mail_message.rb
92
+ - sample/Open_file_in_TextEdit.rb
93
+ - sample/Organize_Mail_messages.rb
94
+ - sample/Print_folder_tree.rb
95
+ - sample/Select_all_HTML_files.rb
96
+ - sample/Set_iChat_status.rb
97
+ - sample/Simple_Finder_GUI_Scripting.rb
98
+ - sample/Stagger_Finder_windows.rb
99
+ - sample/TextEdit_demo.rb
100
+ - src/lib
101
+ - src/rbae.c
102
+ - src/lib/_aem
103
+ - src/lib/_appscript
104
+ - src/lib/aem.rb
105
+ - src/lib/appscript.rb
106
+ - src/lib/kae.rb
107
+ - src/lib/osax.rb
108
+ - src/lib/_aem/aemreference.rb
109
+ - src/lib/_aem/codecs.rb
110
+ - src/lib/_aem/connect.rb
111
+ - src/lib/_aem/findapp.rb
112
+ - src/lib/_aem/mactypes.rb
113
+ - src/lib/_aem/send.rb
114
+ - src/lib/_aem/typewrappers.rb
115
+ - src/lib/_appscript/defaultterminology.rb
116
+ - src/lib/_appscript/referencerenderer.rb
117
+ - src/lib/_appscript/reservedkeywords.rb
118
+ - src/lib/_appscript/terminology.rb
119
+ - test/README
120
+ - test/test_aemreference.rb
121
+ - test/test_appscriptreference.rb
122
+ - test/test_codecs.rb
123
+ - test/test_findapp.rb
124
+ - test/test_mactypes.rb
125
+ - test/testall.sh
126
+ test_files:
127
+ - test/test_aemreference.rb
128
+ - test/test_appscriptreference.rb
129
+ - test/test_codecs.rb
130
+ - test/test_findapp.rb
131
+ - test/test_mactypes.rb
132
+ rdoc_options: []
133
+
134
+ extra_rdoc_files: []
135
+
136
+ executables: []
137
+
138
+ extensions:
139
+ - extconf.rb
140
+ requirements: []
141
+
142
+ dependencies: []
143
+