rb-scpt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +497 -0
- data/doc/aem-manual/01_introduction.html +60 -0
- data/doc/aem-manual/02_apioverview.html +107 -0
- data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
- data/doc/aem-manual/04_references.html +409 -0
- data/doc/aem-manual/05_targetingapplications.html +164 -0
- data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
- data/doc/aem-manual/07_findapp.html +63 -0
- data/doc/aem-manual/08_examples.html +94 -0
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/index.html +56 -0
- data/doc/appscript-manual/01_introduction.html +94 -0
- data/doc/appscript-manual/02_aboutappscripting.html +247 -0
- data/doc/appscript-manual/03_quicktutorial.html +167 -0
- data/doc/appscript-manual/04_gettinghelp.html +188 -0
- data/doc/appscript-manual/05_keywordconversion.html +106 -0
- data/doc/appscript-manual/06_classesandenums.html +192 -0
- data/doc/appscript-manual/07_applicationobjects.html +211 -0
- data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
- data/doc/appscript-manual/09_referenceforms.html +241 -0
- data/doc/appscript-manual/10_referenceexamples.html +154 -0
- data/doc/appscript-manual/11_applicationcommands.html +245 -0
- data/doc/appscript-manual/12_commandexamples.html +138 -0
- data/doc/appscript-manual/13_performanceissues.html +142 -0
- data/doc/appscript-manual/14_notes.html +80 -0
- data/doc/appscript-manual/application_architecture.gif +0 -0
- data/doc/appscript-manual/application_architecture2.gif +0 -0
- data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
- data/doc/appscript-manual/index.html +62 -0
- data/doc/appscript-manual/relationships_example.gif +0 -0
- data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
- data/doc/full.css +106 -0
- data/doc/index.html +45 -0
- data/doc/mactypes-manual/01_introduction.html +54 -0
- data/doc/mactypes-manual/02_aliasclass.html +124 -0
- data/doc/mactypes-manual/03_fileurlclass.html +126 -0
- data/doc/mactypes-manual/04_unitsclass.html +100 -0
- data/doc/mactypes-manual/index.html +53 -0
- data/doc/osax-manual/01_introduction.html +67 -0
- data/doc/osax-manual/02_interface.html +147 -0
- data/doc/osax-manual/03_examples.html +73 -0
- data/doc/osax-manual/04_notes.html +61 -0
- data/doc/osax-manual/index.html +53 -0
- data/doc/rb-appscript-logo.png +0 -0
- data/extconf.rb +65 -0
- data/rb-scpt.gemspec +14 -0
- data/sample/AB_export_vcard.rb +31 -0
- data/sample/AB_list_people_with_emails.rb +13 -0
- data/sample/Add_iCal_event.rb +21 -0
- data/sample/Create_daily_iCal_todos.rb +75 -0
- data/sample/Export_Address_Book_phone_numbers.rb +59 -0
- data/sample/Hello_world.rb +21 -0
- data/sample/List_iTunes_playlist_names.rb +11 -0
- data/sample/Make_Mail_message.rb +33 -0
- data/sample/Open_file_in_TextEdit.rb +13 -0
- data/sample/Organize_Mail_messages.rb +61 -0
- data/sample/Print_folder_tree.rb +16 -0
- data/sample/Select_all_HTML_files.rb +14 -0
- data/sample/Set_iChat_status.rb +24 -0
- data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
- data/sample/Stagger_Finder_windows.rb +25 -0
- data/sample/TextEdit_demo.rb +130 -0
- data/sample/iTunes_top40_to_html.rb +71 -0
- data/src/SendThreadSafe.c +380 -0
- data/src/SendThreadSafe.h +139 -0
- data/src/lib/_aem/aemreference.rb +1022 -0
- data/src/lib/_aem/codecs.rb +662 -0
- data/src/lib/_aem/connect.rb +205 -0
- data/src/lib/_aem/encodingsupport.rb +77 -0
- data/src/lib/_aem/findapp.rb +85 -0
- data/src/lib/_aem/mactypes.rb +251 -0
- data/src/lib/_aem/send.rb +279 -0
- data/src/lib/_aem/typewrappers.rb +59 -0
- data/src/lib/_appscript/defaultterminology.rb +277 -0
- data/src/lib/_appscript/referencerenderer.rb +245 -0
- data/src/lib/_appscript/reservedkeywords.rb +116 -0
- data/src/lib/_appscript/safeobject.rb +249 -0
- data/src/lib/_appscript/terminology.rb +471 -0
- data/src/lib/aem.rb +253 -0
- data/src/lib/appscript.rb +1075 -0
- data/src/lib/kae.rb +1489 -0
- data/src/lib/osax.rb +659 -0
- data/src/rbae.c +979 -0
- data/test/README +3 -0
- data/test/test_aemreference.rb +118 -0
- data/test/test_appscriptcommands.rb +152 -0
- data/test/test_appscriptreference.rb +106 -0
- data/test/test_codecs.rb +186 -0
- data/test/test_findapp.rb +26 -0
- data/test/test_mactypes.rb +79 -0
- data/test/test_osax.rb +54 -0
- data/test/testall.sh +10 -0
- metadata +145 -0
data/test/README
ADDED
@@ -0,0 +1,3 @@
|
|
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, OS X 10.4.x (PPC & i386) and OS X 10.5.1 (i386).
|
2
|
+
|
3
|
+
Note that some mactypes unit tests may fail as Alias and FileURL comparisons are rather dumb and don't normalise path strings before comparing/hashing. Future releases may try to remedy this.
|
@@ -0,0 +1,118 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
begin; require 'rubygems'; rescue LoadError; end
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require "_aem/aemreference"
|
7
|
+
require "_aem/typewrappers"
|
8
|
+
require "_aem/codecs"
|
9
|
+
|
10
|
+
|
11
|
+
class TC_AEMReferences < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def test_reference_forms
|
14
|
+
[
|
15
|
+
[AEMReference::App.property('ctxt'), 'AEM.app.property("ctxt")', nil],
|
16
|
+
|
17
|
+
[AEMReference::App.elements('docu'), 'AEM.app.elements("docu")', nil],
|
18
|
+
|
19
|
+
[AEMReference::App.elements('docu').by_index(1),
|
20
|
+
'AEM.app.elements("docu").by_index(1)', nil],
|
21
|
+
[AEMReference::App.elements('docu').by_name('foo'),
|
22
|
+
'AEM.app.elements("docu").by_name("foo")', nil],
|
23
|
+
[AEMReference::App.elements('docu').by_id(300),
|
24
|
+
'AEM.app.elements("docu").by_id(300)', nil],
|
25
|
+
|
26
|
+
[AEMReference::App.elements('docu').next('docu'),
|
27
|
+
'AEM.app.elements("docu").next("docu")', nil],
|
28
|
+
[AEMReference::App.elements('docu').previous('docu'),
|
29
|
+
'AEM.app.elements("docu").previous("docu")', nil],
|
30
|
+
|
31
|
+
[AEMReference::App.elements('docu').first, 'AEM.app.elements("docu").first', nil],
|
32
|
+
[AEMReference::App.elements('docu').middle, 'AEM.app.elements("docu").middle', nil],
|
33
|
+
[AEMReference::App.elements('docu').last, 'AEM.app.elements("docu").last', nil],
|
34
|
+
[AEMReference::App.elements('docu').any, 'AEM.app.elements("docu").any', nil],
|
35
|
+
|
36
|
+
[AEMReference::Con.elements("docu").by_index(3), 'AEM.con.elements("docu").by_index(3)', nil],
|
37
|
+
|
38
|
+
[AEMReference::App.elements('docu').by_range(
|
39
|
+
AEMReference::Con.elements('docu').by_index(3),
|
40
|
+
AEMReference::Con.elements('docu').by_name('foo')),
|
41
|
+
'AEM.app.elements("docu").by_range(' +
|
42
|
+
'AEM.con.elements("docu").by_index(3), ' +
|
43
|
+
'AEM.con.elements("docu").by_name("foo"))', nil],
|
44
|
+
|
45
|
+
[AEMReference::App.elements('docu').by_range(1, 'foo'),
|
46
|
+
'AEM.app.elements("docu").by_range(1, "foo")',
|
47
|
+
AEMReference::App.elements("docu").by_range(
|
48
|
+
AEMReference::Con.elements("docu").by_index(1),
|
49
|
+
AEMReference::Con.elements("docu").by_name("foo"))],
|
50
|
+
|
51
|
+
[AEMReference::Its.property('name').eq('foo').and(AEMReference::Its.elements('cwor').eq([])),
|
52
|
+
'AEM.its.property("name").eq("foo").and(AEM.its.elements("cwor").eq([]))', nil],
|
53
|
+
|
54
|
+
[AEMReference::Its.elements('cwor').ne([]),
|
55
|
+
'AEM.its.elements("cwor").ne([])',
|
56
|
+
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
|
57
|
+
|
58
|
+
[AEMReference::Its.elements('cwor').eq(nil), 'AEM.its.elements("cwor").eq(nil)', nil],
|
59
|
+
[AEMReference::Its.elements('cwor').property('leng').gt(0),
|
60
|
+
'AEM.its.elements("cwor").property("leng").gt(0)', nil],
|
61
|
+
[AEMReference::Its.elements('cwor').le(''), 'AEM.its.elements("cwor").le("")', nil],
|
62
|
+
[AEMReference::Its.elements('cwor').begins_with('foo').not,
|
63
|
+
'AEM.its.elements("cwor").begins_with("foo").not', nil],
|
64
|
+
|
65
|
+
|
66
|
+
[AEMReference::Its.elements('cwor').contains('foo'), 'AEM.its.elements("cwor").contains("foo")', nil],
|
67
|
+
[AEMReference::Its.elements('cwor').is_in('foo'), 'AEM.its.elements("cwor").is_in("foo")', nil],
|
68
|
+
|
69
|
+
[AEMReference::App.elements('docu').by_filter(AEMReference::Its.property('size').ge(42)),
|
70
|
+
'AEM.app.elements("docu").by_filter(AEM.its.property("size").ge(42))', nil],
|
71
|
+
|
72
|
+
[AEMReference::App.elements('docu').by_index(1).property('ctxt') \
|
73
|
+
.elements('cpar').elements('cha ').by_range(
|
74
|
+
AEMReference::Con.elements('cha ').by_index(3),
|
75
|
+
AEMReference::Con.elements('cha ').by_index(55)
|
76
|
+
).next('cha ').after,
|
77
|
+
'AEM.app.elements("docu").by_index(1).property("ctxt").elements("cpar").elements("cha ")' +
|
78
|
+
'.by_range(AEM.con.elements("cha ").by_index(3), AEM.con.elements("cha ").by_index(55))' +
|
79
|
+
'.next("cha ").after', nil],
|
80
|
+
|
81
|
+
[AEMReference::Its.property('pnam').ne('foo').and(AEMReference::Its.elements('cfol').eq([])).not,
|
82
|
+
'AEM.its.property("pnam").ne("foo").and(AEM.its.elements("cfol").eq([])).not',
|
83
|
+
AEMReference::Its.property('pnam').eq('foo').not.and(AEMReference::Its.elements('cfol').eq([])).not],
|
84
|
+
|
85
|
+
[AEMReference::App.elements('docu').beginning, 'AEM.app.elements("docu").beginning', nil],
|
86
|
+
[AEMReference::App.elements('docu').end, 'AEM.app.elements("docu").end', nil],
|
87
|
+
[AEMReference::App.elements('docu').by_index(3).before, 'AEM.app.elements("docu").by_index(3).before', nil],
|
88
|
+
[AEMReference::App.elements('docu').by_name('foo').after, 'AEM.app.elements("docu").by_name("foo").after', nil],
|
89
|
+
|
90
|
+
].each do |val, res, unpacked_version|
|
91
|
+
begin
|
92
|
+
assert_equal(res, val.to_s)
|
93
|
+
d = DefaultCodecs.pack(val)
|
94
|
+
val = unpacked_version ? unpacked_version : val
|
95
|
+
val2 = DefaultCodecs.unpack(d)
|
96
|
+
assert_equal(val, val2)
|
97
|
+
val2 = DefaultCodecs.unpack(d)
|
98
|
+
assert_block { val.eql?(val2) }
|
99
|
+
val2 = DefaultCodecs.unpack(d)
|
100
|
+
assert_equal(val2, val)
|
101
|
+
val2 = DefaultCodecs.unpack(d)
|
102
|
+
assert_block { val2.eql?(val) }
|
103
|
+
rescue
|
104
|
+
puts 'EXPECTED: ' + res
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
end
|
108
|
+
assert_not_equal(AEMReference::App.property('ctxt').property('ctxt'), AEMReference::Con.property('ctxt').property('ctxt'))
|
109
|
+
assert_not_equal(AEMReference::App.property('foob').property('ctxt'), AEMReference::App.property('ctxt').property('ctxt'))
|
110
|
+
assert_not_equal(AEMReference::App.elements('ctxt').property('ctxt'), AEMReference::App.property('ctxt').property('ctxt'))
|
111
|
+
assert_not_equal(AEMReference::App.elements('ctxt').property('ctxt'), 333)
|
112
|
+
assert_not_equal(333, AEMReference::App.property('ctxt').property('ctxt'))
|
113
|
+
# # by-filter references do basic type checking to ensure an its-based reference is given
|
114
|
+
assert_raises(TypeError) { AEMReference::App.elements('docu').by_filter(1) }
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
begin; require 'rubygems'; rescue LoadError; end
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'appscript'
|
7
|
+
|
8
|
+
# rb-appscript 0.5.0+ should no longer require the following kludge:
|
9
|
+
#class AS_SafeObject
|
10
|
+
# def self.hide(name)
|
11
|
+
# end
|
12
|
+
#end
|
13
|
+
|
14
|
+
class TC_AppscriptNewApp < Test::Unit::TestCase
|
15
|
+
|
16
|
+
def test_by_name
|
17
|
+
[
|
18
|
+
'/Applications/TextEdit.app',
|
19
|
+
'Finder.app',
|
20
|
+
'System Events'
|
21
|
+
].each do |name|
|
22
|
+
a = Appscript.app(name)
|
23
|
+
assert_not_nil(a)
|
24
|
+
assert_instance_of(Appscript::Application, a)
|
25
|
+
assert_instance_of(Appscript::Reference, a.name)
|
26
|
+
end
|
27
|
+
assert_equal('app("/Applications/TextEdit.app")', Appscript.app('TextEdit').to_s)
|
28
|
+
assert_equal('app("/Applications/TextEdit.app")', Appscript.app.by_name('TextEdit').to_s)
|
29
|
+
|
30
|
+
assert_raises(Appscript::ApplicationNotFoundError) { Appscript.app('/non-existent/app') }
|
31
|
+
assert_raises(Appscript::ApplicationNotFoundError) { Appscript.app('non-existent.app') }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_by_id
|
35
|
+
[
|
36
|
+
'com.apple.textedit',
|
37
|
+
'com.apple.finder',
|
38
|
+
].each do |name|
|
39
|
+
a = Appscript.app.by_id(name)
|
40
|
+
assert_not_nil(a)
|
41
|
+
assert_instance_of(Appscript::Application, a)
|
42
|
+
assert_instance_of(Appscript::Reference, a.name)
|
43
|
+
end
|
44
|
+
assert_equal('app("/Applications/TextEdit.app")', Appscript.app.by_id('com.apple.textedit').to_s)
|
45
|
+
|
46
|
+
assert_raises(Appscript::ApplicationNotFoundError) { Appscript.app.by_id('non.existent.app') }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_by_creator
|
50
|
+
a = Appscript.app.by_creator('ttxt')
|
51
|
+
assert_instance_of(Appscript::Reference, a.name)
|
52
|
+
assert_equal('app("/Applications/TextEdit.app")', a.to_s)
|
53
|
+
assert_raises(Appscript::ApplicationNotFoundError) { Appscript.app.by_id('!@$o') }
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_by_pid
|
57
|
+
pid = `top -l1 | grep Finder | awk '{ print $1 }'`.to_i # note: this line will return a bad result if more than one user is logged in
|
58
|
+
a = Appscript.app.by_pid(pid)
|
59
|
+
assert_instance_of(Appscript::Reference, a.name)
|
60
|
+
assert_equal("app.by_pid(#{pid})", a.to_s)
|
61
|
+
assert_equal('Finder', a.name.get)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_by_aem_app
|
65
|
+
a = Appscript.app.by_aem_app(AEM::Application.by_path('/Applications/TextEdit.app'))
|
66
|
+
assert_instance_of(Appscript::Reference, a.name)
|
67
|
+
assert_equal('app.by_aem_app(AEM::Application.by_path("/Applications/TextEdit.app"))', a.to_s)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
class TC_AppscriptCommands < Test::Unit::TestCase
|
73
|
+
|
74
|
+
def setup
|
75
|
+
@te = Appscript.app('TextEdit')
|
76
|
+
@f = Appscript.app('Finder')
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_commands_1
|
80
|
+
assert_equal('TextEdit', @te.name.get)
|
81
|
+
d = @te.make(:new=>:document, :with_properties=>{:text=>'test test_commands'})
|
82
|
+
assert_instance_of(Appscript::Reference, d)
|
83
|
+
d.text.end.make(:new=>:word, :with_data=>' test2')
|
84
|
+
assert_equal('test test_commands test2', d.text.get)
|
85
|
+
assert_instance_of(String,
|
86
|
+
d.text.get(:ignore=>[:diacriticals, :punctuation, :whitespace, :expansion], :timeout=>10))
|
87
|
+
assert_nil(d.get(:wait_reply=>false))
|
88
|
+
|
89
|
+
|
90
|
+
# test Ruby 1.9+ String Encoding support
|
91
|
+
version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
|
92
|
+
if version >= 1 and sub_version >= 9
|
93
|
+
|
94
|
+
print "(check Encoding support)"
|
95
|
+
s = "\302\251 M. Lef\303\250vre"
|
96
|
+
s.force_encoding('utf-8')
|
97
|
+
d.text.set(s)
|
98
|
+
assert_equal(s, d.text.get)
|
99
|
+
|
100
|
+
@te.AS_app_data.use_ascii_8bit
|
101
|
+
end
|
102
|
+
|
103
|
+
d.text.set("\302\251 M. Lef\303\250vre")
|
104
|
+
assert_equal("\302\251 M. Lef\303\250vre", d.text.get)
|
105
|
+
|
106
|
+
d.close(:saving=>:no)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_commands_2
|
110
|
+
d = @te.make(:new=>:document, :at=>@te.documents.end)
|
111
|
+
|
112
|
+
@te.set(d.text, :to=> 'test1')
|
113
|
+
assert_equal('test1', d.text.get)
|
114
|
+
|
115
|
+
@te.set(d.text, :to=> 'test2')
|
116
|
+
@te.make(:new=>:word, :at=>Appscript.app.documents[1].paragraphs.end, :with_data=>' test3')
|
117
|
+
assert_equal('test2 test3', d.text.get)
|
118
|
+
|
119
|
+
d.close(:saving=>:no)
|
120
|
+
|
121
|
+
assert_raises(Appscript::CommandError) { @te.documents[10000].get }
|
122
|
+
|
123
|
+
assert_instance_of(Fixnum, @te.documents.count)
|
124
|
+
assert_equal(@te.documents.count, @te.count(:each=>:document))
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_commands_3
|
128
|
+
assert_equal('Finder', @f.name.get)
|
129
|
+
val = @f.home.folders['Desktop'].get(:result_type=>:alias)
|
130
|
+
assert_instance_of(MacTypes::Alias, val)
|
131
|
+
assert_equal(val, @f.desktop.get(:result_type=>:alias))
|
132
|
+
assert_instance_of(Array, @f.disks.get)
|
133
|
+
|
134
|
+
r = @f.home.get
|
135
|
+
f = r.get(:result_type=>:file_ref)
|
136
|
+
assert_equal(r, @f.items[f].get)
|
137
|
+
|
138
|
+
assert_equal(@f.home.items.get, @f.home.items.get)
|
139
|
+
assert_not_equal(@f.disks['non-existent'], @f.disks[1].get)
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_command_error
|
143
|
+
begin
|
144
|
+
@f.items[10000].get
|
145
|
+
rescue Appscript::CommandError => e
|
146
|
+
assert_equal(-1728, e.to_i)
|
147
|
+
assert_equal("CommandError\n\t\tOSERROR: -1728\n\t\tMESSAGE: Can't get reference.\n\t\tOFFENDING OBJECT: app(\"/System/Library/CoreServices/Finder.app\").items[10000]\n\t\tCOMMAND: app(\"/System/Library/CoreServices/Finder.app\").items[10000].get()\n", e.to_s)
|
148
|
+
assert_instance_of(AEM::EventError, e.real_error)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
begin; require 'rubygems'; rescue LoadError; end
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require "appscript"
|
7
|
+
|
8
|
+
class TC_AppscriptReferences < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@te = Appscript.app('TextEdit')
|
12
|
+
@s = @te.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_reference_forms
|
16
|
+
[
|
17
|
+
|
18
|
+
[@te.documents[
|
19
|
+
Appscript.con.documents[3],
|
20
|
+
Appscript.con.documents['foo']],
|
21
|
+
@s+'.documents[' +
|
22
|
+
'con.documents[3], ' +
|
23
|
+
'con.documents["foo"]]', nil],
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
[@te.text, @s+'.text', nil],
|
28
|
+
|
29
|
+
[@te.documents, @s+'.documents', nil],
|
30
|
+
|
31
|
+
[@te.documents[1],
|
32
|
+
@s+'.documents[1]', nil],
|
33
|
+
[@te.documents['foo'],
|
34
|
+
@s+'.documents["foo"]', nil],
|
35
|
+
[@te.documents.ID(300),
|
36
|
+
@s+'.documents.ID(300)', nil],
|
37
|
+
|
38
|
+
[@te.documents.next(:document),
|
39
|
+
@s+'.documents.next(:document)', nil],
|
40
|
+
[@te.documents.previous(:document),
|
41
|
+
@s+'.documents.previous(:document)', nil],
|
42
|
+
|
43
|
+
[@te.documents.first, @s+'.documents.first', nil],
|
44
|
+
[@te.documents.middle, @s+'.documents.middle', nil],
|
45
|
+
[@te.documents.last, @s+'.documents.last', nil],
|
46
|
+
[@te.documents.any, @s+'.documents.any', nil],
|
47
|
+
|
48
|
+
[Appscript.con.documents[3], 'con.documents[3]', nil],
|
49
|
+
|
50
|
+
|
51
|
+
[Appscript.its.name.eq('foo').and(Appscript.its.words.eq([])),
|
52
|
+
'its.name.eq("foo").and(its.words.eq([]))', nil],
|
53
|
+
|
54
|
+
[Appscript.its.words.ne([]),
|
55
|
+
'its.words.ne([])',
|
56
|
+
Appscript.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
|
57
|
+
|
58
|
+
[Appscript.its.words.eq(nil), 'its.words.eq(nil)', nil],
|
59
|
+
[Appscript.its.words.size.gt(0),
|
60
|
+
'its.words.size.gt(0)', nil],
|
61
|
+
[Appscript.its.words.le(''), 'its.words.le("")', nil],
|
62
|
+
[Appscript.its.words.begins_with('foo').not,
|
63
|
+
'its.words.begins_with("foo").not', nil],
|
64
|
+
|
65
|
+
|
66
|
+
[Appscript.its.words.contains('foo'), 'its.words.contains("foo")', nil],
|
67
|
+
[Appscript.its.words.is_in('foo'), 'its.words.is_in("foo")', nil],
|
68
|
+
|
69
|
+
[@te.documents[Appscript.its.size.ge(42)],
|
70
|
+
@s+'.documents[its.size.ge(42)]', nil],
|
71
|
+
|
72
|
+
[@te.documents[1, 'foo'],
|
73
|
+
@s+'.documents[1, "foo"]',
|
74
|
+
@te.documents[Appscript.con.documents[1], Appscript.con.documents["foo"]]],
|
75
|
+
|
76
|
+
[@te.documents[1].text \
|
77
|
+
.paragraphs.characters[
|
78
|
+
Appscript.con.characters[3],
|
79
|
+
Appscript.con.characters[55]
|
80
|
+
].next(:character).after,
|
81
|
+
@s+'.documents[1].text.paragraphs.characters' +
|
82
|
+
'[con.characters[3], con.characters[55]]' +
|
83
|
+
'.next(:character).after', nil],
|
84
|
+
|
85
|
+
[Appscript.its.name.ne('foo').and(Appscript.its.words.eq([])).not,
|
86
|
+
'its.name.ne("foo").and(its.words.eq([])).not',
|
87
|
+
Appscript.its.name.eq('foo').not.and(Appscript.its.words.eq([])).not],
|
88
|
+
|
89
|
+
[@te.documents.beginning, @s+'.documents.beginning', nil],
|
90
|
+
[@te.documents.end, @s+'.documents.end', nil],
|
91
|
+
[@te.documents[3].before, @s+'.documents[3].before', nil],
|
92
|
+
[@te.documents['foo'].after, @s+'.documents["foo"].after', nil],
|
93
|
+
|
94
|
+
].each do |val, res, unpacked_version|
|
95
|
+
assert_equal(res, val.to_s)
|
96
|
+
d = @te.AS_app_data.pack(val)
|
97
|
+
val = unpacked_version ? unpacked_version : val
|
98
|
+
val2 = @te.AS_app_data.unpack(d)
|
99
|
+
if val.class == @te.AS_app_data.unpack(d).class # note: Appscript::Reference and Appscript::GenericReference currently aren't comparable with each other, so the next test would always fail for those
|
100
|
+
assert_equal(val, val2)
|
101
|
+
assert_block { val.eql?(val2) }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
data/test/test_codecs.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
begin; require 'rubygems'; rescue LoadError; end
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'aem'
|
7
|
+
require 'kae'
|
8
|
+
require 'ae'
|
9
|
+
|
10
|
+
def num(s)
|
11
|
+
if [1].pack('s') == "\001\000" # host system is i386
|
12
|
+
s.reverse
|
13
|
+
else
|
14
|
+
s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def ut16(s)
|
19
|
+
if [1].pack('s') == "\001\000" # host system is i386
|
20
|
+
i = 0
|
21
|
+
s2 = ''
|
22
|
+
(s.length / 2).times do
|
23
|
+
s2 += s[i, 2].reverse
|
24
|
+
i+=2
|
25
|
+
end
|
26
|
+
s2
|
27
|
+
else
|
28
|
+
s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
class TC_Codecs < Test::Unit::TestCase
|
36
|
+
|
37
|
+
def setup
|
38
|
+
@c = AEM::Codecs.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_nil
|
42
|
+
d = @c.pack(nil)
|
43
|
+
assert_equal(KAE::TypeNull, d.type)
|
44
|
+
assert_equal('', d.data)
|
45
|
+
assert_nil(@c.unpack(d))
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_bool
|
49
|
+
[
|
50
|
+
[true, KAE::TypeTrue],
|
51
|
+
[false, KAE::TypeFalse]
|
52
|
+
].each do |val, type|
|
53
|
+
d = @c.pack(val)
|
54
|
+
assert_equal(type, d.type)
|
55
|
+
assert_equal('', d.data)
|
56
|
+
assert_equal(val, @c.unpack(d))
|
57
|
+
end
|
58
|
+
assert_equal(true, @c.unpack(AE::AEDesc.new(KAE::TypeBoolean, "\xfe")))
|
59
|
+
assert_equal(true, @c.unpack(AE::AEDesc.new(KAE::TypeTrue, '')))
|
60
|
+
assert_equal(false, @c.unpack(AE::AEDesc.new(KAE::TypeFalse, '')))
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_num
|
64
|
+
[ # (mostly testing at threshold points where Codecs switches types when packing integers)
|
65
|
+
[0, "\x00\x00\x00\x00", KAE::TypeInteger],
|
66
|
+
[2, "\x00\x00\x00\x02", KAE::TypeInteger],
|
67
|
+
[-9, "\xff\xff\xff\xf7", KAE::TypeInteger],
|
68
|
+
[2**31-1, "\x7f\xff\xff\xff", KAE::TypeInteger],
|
69
|
+
[-2**31, "\x80\x00\x00\x00", KAE::TypeInteger],
|
70
|
+
[2**31, "\x00\x00\x00\x00\x80\x00\x00\x00", KAE::TypeSInt64],
|
71
|
+
[2**32-1, "\x00\x00\x00\x00\xff\xff\xff\xff", KAE::TypeSInt64],
|
72
|
+
[2**32, "\x00\x00\x00\x01\x00\x00\x00\x00", KAE::TypeSInt64],
|
73
|
+
[-2**32, "\xff\xff\xff\xff\x00\x00\x00\x00", KAE::TypeSInt64],
|
74
|
+
[2**63-1, "\x7f\xff\xff\xff\xff\xff\xff\xff", KAE::TypeSInt64],
|
75
|
+
[-2**63, "\x80\x00\x00\x00\x00\x00\x00\x00", KAE::TypeSInt64],
|
76
|
+
[-2**63+1, "\x80\x00\x00\x00\x00\x00\x00\x01", KAE::TypeSInt64],
|
77
|
+
[2**63, "C\xe0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
|
78
|
+
[-2**63-1, "\xc3\xe0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
|
79
|
+
[0.1, "?\xb9\x99\x99\x99\x99\x99\x9a", KAE::TypeFloat],
|
80
|
+
[-0.9e-9, "\xbe\x0e\xec{\xd5\x12\xb5r", KAE::TypeFloat],
|
81
|
+
[2**300, "R\xb0\x00\x00\x00\x00\x00\x00", KAE::TypeFloat],
|
82
|
+
].each do |val, data, type|
|
83
|
+
data = num(data)
|
84
|
+
d = @c.pack(val)
|
85
|
+
assert_equal(type, d.type)
|
86
|
+
assert_equal(data, d.data)
|
87
|
+
assert_equal(val, @c.unpack(d))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_str
|
92
|
+
s = "\xc6\x92\xe2\x88\x82\xc2\xae\xd4\xb7\xd5\x96\xd4\xb9\xe0\xa8\x89\xe3\x82\xa2\xe3\x84\xbb"
|
93
|
+
# test Ruby 1.9+ String Encoding support
|
94
|
+
version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
|
95
|
+
if version >= 1 and sub_version >= 9
|
96
|
+
s.force_encoding('utf-8')
|
97
|
+
end
|
98
|
+
|
99
|
+
[
|
100
|
+
# 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.
|
101
|
+
# 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
|
102
|
+
['', ''],
|
103
|
+
['hello', "\000h\000e\000l\000l\000o"],
|
104
|
+
[s, "\x01\x92\"\x02\x00\xae\x057\x05V\x059\n\t0\xa21;"],
|
105
|
+
].each do |val, data|
|
106
|
+
data = ut16(data)
|
107
|
+
d = @c.pack(val)
|
108
|
+
assert_equal(KAE::TypeUnicodeText, d.type)
|
109
|
+
assert_equal(data, d.data)
|
110
|
+
assert_equal(val, @c.unpack(d))
|
111
|
+
end
|
112
|
+
assert_raises(TypeError) { @c.pack("\x88") } # non-valid UTF8 strings should raise error when coercing from typeUTF8Text to typeUnicodeText
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_date
|
116
|
+
# note: not testing on ST-DST boundaries; this is known to have out-by-an-hour problems due to LongDateTime type being crap
|
117
|
+
[
|
118
|
+
[Time.local(2005, 12, 11, 15, 40, 43), "\x00\x00\x00\x00\xbf\xc1\xf8\xfb"],
|
119
|
+
[Time.local(2005, 5, 1, 6, 51, 7), "\x00\x00\x00\x00\xbe\x9a\x2c\xdb"],
|
120
|
+
].each do |t, data|
|
121
|
+
data = num(data)
|
122
|
+
d = @c.pack(t)
|
123
|
+
assert_equal(KAE::TypeLongDateTime, d.type)
|
124
|
+
assert_equal(data, d.data)
|
125
|
+
assert_equal(t, @c.unpack(AE::AEDesc.new(KAE::TypeLongDateTime, data)))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_file
|
130
|
+
path = '/Applications/TextEdit.app'
|
131
|
+
d = @c.pack(MacTypes::Alias.path(path))
|
132
|
+
assert_equal(path, @c.unpack(d).to_s)
|
133
|
+
|
134
|
+
path = '/Applications/TextEdit.app'
|
135
|
+
d = @c.pack(MacTypes::FileURL.path(path))
|
136
|
+
assert_equal(path, @c.unpack(d).to_s)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_typewrappers
|
140
|
+
[
|
141
|
+
AEM::AEType.new("docu"),
|
142
|
+
AEM::AEEnum.new('yes '),
|
143
|
+
AEM::AEProp.new('pnam'),
|
144
|
+
AEM::AEKey.new('ABCD'),
|
145
|
+
].each do |val|
|
146
|
+
d = @c.pack(val)
|
147
|
+
val2 = @c.unpack(d)
|
148
|
+
assert_equal(val, val2)
|
149
|
+
assert_block { val.eql?(val2) }
|
150
|
+
val2 = @c.unpack(d)
|
151
|
+
assert_equal(val2, val)
|
152
|
+
assert_block { val2.eql?(val) }
|
153
|
+
end
|
154
|
+
assert_raises(ArgumentError) { AEM::AEType.new(3) }
|
155
|
+
assert_raises(ArgumentError) { AEM::AEType.new("docum") }
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_list
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_hash
|
162
|
+
val = {'foo' => 1, AEM::AEType.new('foob') => 2, AEM::AEProp.new('barr') => 3}
|
163
|
+
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
|
164
|
+
d = @c.pack(val)
|
165
|
+
assert_equal(expected_val, @c.unpack(d))
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_units
|
169
|
+
val = MacTypes::Units.new(3.3, :inches)
|
170
|
+
assert_equal(:inches, val.type)
|
171
|
+
assert_equal(3.3, val.value)
|
172
|
+
d = @c.pack(val)
|
173
|
+
assert_equal('inch', d.type)
|
174
|
+
assert_equal(3.3, @c.unpack(d.coerce(KAE::TypeFloat)))
|
175
|
+
val2 = @c.unpack(d)
|
176
|
+
assert_equal(val, val2)
|
177
|
+
assert_equal(:inches, val2.type)
|
178
|
+
assert_equal(3.3, val2.value)
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_app
|
182
|
+
val = AEM::Application.by_path(FindApp.by_name('TextEdit'))
|
183
|
+
d = @c.pack(val)
|
184
|
+
assert_equal(KAE::TypeProcessSerialNumber, d.type)
|
185
|
+
end
|
186
|
+
end
|