rb-scpt 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rb-scpt-1.0.1.gem +0 -0
  3. data/extconf.rb +12 -12
  4. data/rb-scpt.gemspec +10 -10
  5. data/sample/AB_export_vcard.rb +16 -16
  6. data/sample/AB_list_people_with_emails.rb +4 -4
  7. data/sample/Add_iCal_event.rb +12 -12
  8. data/sample/Create_daily_iCal_todos.rb +28 -28
  9. data/sample/Export_Address_Book_phone_numbers.rb +52 -52
  10. data/sample/Hello_world.rb +10 -10
  11. data/sample/List_iTunes_playlist_names.rb +3 -3
  12. data/sample/Make_Mail_message.rb +24 -24
  13. data/sample/Open_file_in_TextEdit.rb +5 -5
  14. data/sample/Organize_Mail_messages.rb +46 -46
  15. data/sample/Print_folder_tree.rb +5 -5
  16. data/sample/Select_all_HTML_files.rb +6 -6
  17. data/sample/Set_iChat_status.rb +12 -12
  18. data/sample/Simple_Finder_GUI_Scripting.rb +6 -6
  19. data/sample/Stagger_Finder_windows.rb +9 -9
  20. data/sample/TextEdit_demo.rb +71 -71
  21. data/sample/iTunes_top40_to_html.rb +28 -30
  22. data/src/SendThreadSafe.c +293 -293
  23. data/src/SendThreadSafe.h +108 -108
  24. data/src/lib/_aem/aemreference.rb +997 -998
  25. data/src/lib/_aem/codecs.rb +609 -610
  26. data/src/lib/_aem/connect.rb +197 -197
  27. data/src/lib/_aem/encodingsupport.rb +67 -67
  28. data/src/lib/_aem/findapp.rb +75 -75
  29. data/src/lib/_aem/mactypes.rb +241 -242
  30. data/src/lib/_aem/send.rb +268 -268
  31. data/src/lib/_aem/typewrappers.rb +52 -52
  32. data/src/lib/_appscript/defaultterminology.rb +266 -266
  33. data/src/lib/_appscript/referencerenderer.rb +230 -233
  34. data/src/lib/_appscript/reservedkeywords.rb +106 -106
  35. data/src/lib/_appscript/safeobject.rb +125 -125
  36. data/src/lib/_appscript/terminology.rb +448 -449
  37. data/src/lib/aem.rb +238 -238
  38. data/src/lib/kae.rb +1487 -1487
  39. data/src/lib/osax.rb +647 -647
  40. data/src/lib/rb-scpt.rb +1065 -1065
  41. data/src/rbae.c +595 -595
  42. data/test/test_aemreference.rb +104 -107
  43. data/test/test_appscriptcommands.rb +131 -134
  44. data/test/test_appscriptreference.rb +96 -99
  45. data/test/test_codecs.rb +166 -168
  46. data/test/test_findapp.rb +13 -16
  47. data/test/test_mactypes.rb +70 -72
  48. data/test/test_osax.rb +46 -48
  49. data/test/testall.sh +4 -4
  50. metadata +8 -7
@@ -1,106 +1,103 @@
1
1
  #!/usr/bin/ruby -w
2
2
 
3
- begin; require 'rubygems'; rescue LoadError; end
4
-
5
3
  require 'test/unit'
6
- require "appscript"
4
+ require "rb-scpt"
7
5
 
8
6
  class TC_AppscriptReferences < Test::Unit::TestCase
9
7
 
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
8
+ def setup
9
+ @te = Appscript.app('TextEdit')
10
+ @s = @te.to_s
11
+ end
12
+
13
+ def test_reference_forms
14
+ [
15
+
16
+ [@te.documents[
17
+ Appscript.con.documents[3],
18
+ Appscript.con.documents['foo']],
19
+ @s+'.documents[' +
20
+ 'con.documents[3], ' +
21
+ 'con.documents["foo"]]', nil],
22
+
23
+
24
+
25
+ [@te.text, @s+'.text', nil],
26
+
27
+ [@te.documents, @s+'.documents', nil],
28
+
29
+ [@te.documents[1],
30
+ @s+'.documents[1]', nil],
31
+ [@te.documents['foo'],
32
+ @s+'.documents["foo"]', nil],
33
+ [@te.documents.ID(300),
34
+ @s+'.documents.ID(300)', nil],
35
+
36
+ [@te.documents.next(:document),
37
+ @s+'.documents.next(:document)', nil],
38
+ [@te.documents.previous(:document),
39
+ @s+'.documents.previous(:document)', nil],
40
+
41
+ [@te.documents.first, @s+'.documents.first', nil],
42
+ [@te.documents.middle, @s+'.documents.middle', nil],
43
+ [@te.documents.last, @s+'.documents.last', nil],
44
+ [@te.documents.any, @s+'.documents.any', nil],
45
+
46
+ [Appscript.con.documents[3], 'con.documents[3]', nil],
106
47
 
48
+
49
+ [Appscript.its.name.eq('foo').and(Appscript.its.words.eq([])),
50
+ 'its.name.eq("foo").and(its.words.eq([]))', nil],
51
+
52
+ [Appscript.its.words.ne([]),
53
+ 'its.words.ne([])',
54
+ 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
55
+
56
+ [Appscript.its.words.eq(nil), 'its.words.eq(nil)', nil],
57
+ [Appscript.its.words.size.gt(0),
58
+ 'its.words.size.gt(0)', nil],
59
+ [Appscript.its.words.le(''), 'its.words.le("")', nil],
60
+ [Appscript.its.words.begins_with('foo').not,
61
+ 'its.words.begins_with("foo").not', nil],
62
+
63
+
64
+ [Appscript.its.words.contains('foo'), 'its.words.contains("foo")', nil],
65
+ [Appscript.its.words.is_in('foo'), 'its.words.is_in("foo")', nil],
66
+
67
+ [@te.documents[Appscript.its.size.ge(42)],
68
+ @s+'.documents[its.size.ge(42)]', nil],
69
+
70
+ [@te.documents[1, 'foo'],
71
+ @s+'.documents[1, "foo"]',
72
+ @te.documents[Appscript.con.documents[1], Appscript.con.documents["foo"]]],
73
+
74
+ [@te.documents[1].text \
75
+ .paragraphs.characters[
76
+ Appscript.con.characters[3],
77
+ Appscript.con.characters[55]
78
+ ].next(:character).after,
79
+ @s+'.documents[1].text.paragraphs.characters' +
80
+ '[con.characters[3], con.characters[55]]' +
81
+ '.next(:character).after', nil],
82
+
83
+ [Appscript.its.name.ne('foo').and(Appscript.its.words.eq([])).not,
84
+ 'its.name.ne("foo").and(its.words.eq([])).not',
85
+ Appscript.its.name.eq('foo').not.and(Appscript.its.words.eq([])).not],
86
+
87
+ [@te.documents.beginning, @s+'.documents.beginning', nil],
88
+ [@te.documents.end, @s+'.documents.end', nil],
89
+ [@te.documents[3].before, @s+'.documents[3].before', nil],
90
+ [@te.documents['foo'].after, @s+'.documents["foo"].after', nil],
91
+
92
+ ].each do |val, res, unpacked_version|
93
+ assert_equal(res, val.to_s)
94
+ d = @te.AS_app_data.pack(val)
95
+ val = unpacked_version ? unpacked_version : val
96
+ val2 = @te.AS_app_data.unpack(d)
97
+ 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
98
+ assert_equal(val, val2)
99
+ assert_block { val.eql?(val2) }
100
+ end
101
+ end
102
+ end
103
+ end
@@ -1,186 +1,184 @@
1
1
  #!/usr/bin/ruby -w
2
2
 
3
- begin; require 'rubygems'; rescue LoadError; end
4
-
5
3
  require 'test/unit'
6
4
  require 'aem'
7
5
  require 'kae'
8
6
  require 'ae'
9
7
 
10
8
  def num(s)
11
- if [1].pack('s') == "\001\000" # host system is i386
12
- s.reverse
13
- else
14
- s
15
- end
9
+ if [1].pack('s') == "\001\000" # host system is i386
10
+ s.reverse
11
+ else
12
+ s
13
+ end
16
14
  end
17
15
 
18
16
  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
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
30
28
  end
31
29
 
32
30
 
33
31
 
34
32
 
35
33
  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
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
+ s = "\xc6\x92\xe2\x88\x82\xc2\xae\xd4\xb7\xd5\x96\xd4\xb9\xe0\xa8\x89\xe3\x82\xa2\xe3\x84\xbb"
91
+ # test Ruby 1.9+ String Encoding support
92
+ version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
93
+ if version >= 1 and sub_version >= 9
94
+ s.force_encoding('utf-8')
95
+ end
96
+
97
+ [
98
+ # 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.
99
+ # 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
100
+ ['', ''],
101
+ ['hello', "\000h\000e\000l\000l\000o"],
102
+ [s, "\x01\x92\"\x02\x00\xae\x057\x05V\x059\n\t0\xa21;"],
103
+ ].each do |val, data|
104
+ data = ut16(data)
105
+ d = @c.pack(val)
106
+ assert_equal(KAE::TypeUnicodeText, d.type)
107
+ assert_equal(data, d.data)
108
+ assert_equal(val, @c.unpack(d))
109
+ end
110
+ assert_raises(TypeError) { @c.pack("\x88") } # non-valid UTF8 strings should raise error when coercing from typeUTF8Text to typeUnicodeText
111
+ end
112
+
113
+ def test_date
114
+ # note: not testing on ST-DST boundaries; this is known to have out-by-an-hour problems due to LongDateTime type being crap
115
+ [
116
+ [Time.local(2005, 12, 11, 15, 40, 43), "\x00\x00\x00\x00\xbf\xc1\xf8\xfb"],
117
+ [Time.local(2005, 5, 1, 6, 51, 7), "\x00\x00\x00\x00\xbe\x9a\x2c\xdb"],
118
+ ].each do |t, data|
119
+ data = num(data)
120
+ d = @c.pack(t)
121
+ assert_equal(KAE::TypeLongDateTime, d.type)
122
+ assert_equal(data, d.data)
123
+ assert_equal(t, @c.unpack(AE::AEDesc.new(KAE::TypeLongDateTime, data)))
124
+ end
125
+ end
126
+
127
+ def test_file
128
+ path = '/Applications/TextEdit.app'
129
+ d = @c.pack(MacTypes::Alias.path(path))
130
+ assert_equal(path, @c.unpack(d).to_s)
131
+
132
+ path = '/Applications/TextEdit.app'
133
+ d = @c.pack(MacTypes::FileURL.path(path))
134
+ assert_equal(path, @c.unpack(d).to_s)
135
+ end
136
+
137
+ def test_typewrappers
138
+ [
139
+ AEM::AEType.new("docu"),
140
+ AEM::AEEnum.new('yes '),
141
+ AEM::AEProp.new('pnam'),
142
+ AEM::AEKey.new('ABCD'),
143
+ ].each do |val|
144
+ d = @c.pack(val)
145
+ val2 = @c.unpack(d)
146
+ assert_equal(val, val2)
147
+ assert_block { val.eql?(val2) }
148
+ val2 = @c.unpack(d)
149
+ assert_equal(val2, val)
150
+ assert_block { val2.eql?(val) }
151
+ end
152
+ assert_raises(ArgumentError) { AEM::AEType.new(3) }
153
+ assert_raises(ArgumentError) { AEM::AEType.new("docum") }
154
+ end
155
+
156
+ def test_list
157
+ end
158
+
159
+ def test_hash
160
+ val = {'foo' => 1, AEM::AEType.new('foob') => 2, AEM::AEProp.new('barr') => 3}
161
+ 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
162
+ d = @c.pack(val)
163
+ assert_equal(expected_val, @c.unpack(d))
164
+ end
165
+
166
+ def test_units
167
+ val = MacTypes::Units.new(3.3, :inches)
168
+ assert_equal(:inches, val.type)
169
+ assert_equal(3.3, val.value)
170
+ d = @c.pack(val)
171
+ assert_equal('inch', d.type)
172
+ assert_equal(3.3, @c.unpack(d.coerce(KAE::TypeFloat)))
173
+ val2 = @c.unpack(d)
174
+ assert_equal(val, val2)
175
+ assert_equal(:inches, val2.type)
176
+ assert_equal(3.3, val2.value)
177
+ end
178
+
179
+ def test_app
180
+ val = AEM::Application.by_path(FindApp.by_name('TextEdit'))
181
+ d = @c.pack(val)
182
+ assert_equal(KAE::TypeProcessSerialNumber, d.type)
183
+ end
186
184
  end