Skip Menu |

This queue is for tickets about the Mac-Carbon CPAN distribution.

Report information
The Basics
Id: 20028
Status: resolved
Priority: 0/
Queue: Mac-Carbon

People
Owner: Nobody in particular
Requestors: dha [...] panix.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.75
Fixed in: 0.76



Subject: AppleEvents/t/desc.t, event.t failing
Mac OS 10.4.6 ----- ~/Mac-Carbon-0.75 12:33:36% perl -v This is perl, v5.8.8 built for darwin-2level Copyright 1987-2006, Larry Wall Perl may be copied only under the terms of either the Artistic License or the GNU General Public License, which may be found in the Perl 5 source kit. Complete documentation for Perl, including FAQ lists, should be found on this system using "man perl" or "perldoc perl". If you have access to the Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Subject: desc.out
Download desc.out
application/octet-stream 2.8k

Message body not shown because it is not plain text.

Subject: event.out
Download event.out
application/octet-stream 2.2k

Message body not shown because it is not plain text.

Thanks ... my copy of Test::More was old and incompatible. Try these new tests. I'll do another release today (trying to nail down one more problem someone is having with Mac::Speech).
#!/usr/bin/perl use warnings; use strict; use FindBin '$Bin'; use Test::More tests => 1 + 22 + (8+1146+14+715+495+8) + (13+13+13); BEGIN { use_ok('Mac::AppleEvents'); require "$Bin/helper.pl"; } use Mac::Types; use MacPerl 'MakePath'; my $fourcharcode = ['abcd', '1 ', "\0\0\0\0"]; my $stringdata = ['a', 'ab', 'abc', @$fourcharcode, 'abcde', 'abcdef', "this is some random text I am just gonna add here OK?"]; # 15 my %types = ( # 3 * 5 = 15 typeEnumerated() => $fourcharcode, typeType() => $fourcharcode, typeKeyword() => $fourcharcode, typeApplSignature() => $fourcharcode, typeProperty() => $fourcharcode, # 9 typeChar() => $stringdata, # 2, 3 * 5 = 17 typeBoolean() => [0, 1], typeShortInteger() => [0, 123, -1234], typeInteger() => [0, -2**24, 2**31-1], typeShortFloat() => [0, 123.45, -1234.56], typeFloat() => [0, 12345678.91, (-2**24 + .234234)], typeMagnitude() => [0, 2**32-1, 2**31], # 1 typeFSS() => ['/System/Library/CoreServices/Finder.app'], typeQDRectangle() => [ [1, 240, 320, 2000] ], typeRGBColor() => [ [65535, 0, 0] ], # qdrt, cRGB, STR, STR# ); # = 44 SKIP: { # skip "Basic AEDesc tests", 22; my $desc = AEDesc->new(typeChar); is(ref($desc), 'AEDesc', 'Create AEDesc'); is($desc->type, typeChar, 'Check type'); ok(!defined($desc->get), 'No data'); my $hand = Handle->new('something'); is($desc->type(typeType), typeType, 'Change type'); ok(!defined($desc->get), 'No data'); is(ref($hand), 'Handle', 'Create handle'); ok($desc->data($hand), 'Add handle'); is($desc->get, 'some', 'Check value'); # truncated due to typeType is($desc->type(typeChar), typeChar, 'Change type'); # 6 * 2 = 12 for my $i (0, 1, 10, 100, 1000, 10000) { ok($desc->data(Handle->new($i)), 'Add handle'); is($desc->get, $i, 'Check value'); } ok(AEDisposeDesc($desc), 'Dispose'); } SKIP: { # skip "AEDesc and AEList tests", 8+1146+14+715+495+8; # 8 my $list = AECreateList('', 0); is($list->type, typeAEList, 'Create AEList'); my $reco = AECreateList('', 1); is($reco->type, typeAERecord, 'Create AERecord'); my $list2 = AECreateList('', 0); is($list2->type, typeAEList, 'Create AEList'); my $reco2 = AECreateList('', 1); is($reco2->type, typeAERecord, 'Create AERecord'); my $lists = AEStream->new; is(ref $lists, 'AEStream', 'Create AEStream list'); ok($lists->OpenList, 'OpenList'); my $recos = AEStream->new; is(ref $recos, 'AEStream', 'Create AEStream list'); ok($recos->OpenRecord, 'OpenRecord'); my($listg_fmt, $recog_fmt, @g_param) = ('', ''); # 44 * 4 * 5 = 880, + 44, + 33 * 4 = 132, + 15 * 6 = 90 = 1146 for my $type (sort keys %types) { my $data = $types{$type}; for my $datum (@$data) { my $packed = exists($MacPack{$type}) ? MacPack($type, (ref $datum ? @$datum : $datum)) : $datum; my $desc1 = AEDesc->new($type, $packed); my $desc2 = AEKeyDesc->new($type, $type, $packed); my $desc3 = AECreateDesc($type, $packed); my $desc4 = AEDuplicateDesc($desc1); # http://developer.apple.com/technotes/tn/tn2045.html my $builddata = $datum; my $lit = 0; my $skip = 0; my $hand = 0; if ($type eq typeFSS) { $builddata = $packed; } elsif ($datum =~ /\0/) { $builddata = MakeHex($datum); $lit = 1; } elsif ($type eq typeType) { $builddata = Handle->new(MakeFourChar($datum)); $hand = 1; } elsif ($type eq typeKeyword) { $builddata = MakeFourChar($datum); } elsif ($type eq typeApplSignature || $type eq typeProperty || $type eq typeEnumerated) { $builddata = "'$datum'"; $lit = 1; } elsif ($type eq typeBoolean) { $builddata = MakeNumHex($datum); $lit = 1; } elsif ($type eq typeShortInteger || $type eq typeInteger) { $lit = 1; } elsif (SkipType($type)) { # no idea why this doesn't work, oh well $skip = 1; } my $desc5 = $skip ? '' : $lit ? AEBuild("$type($builddata)") : $hand ? AEBuild("$type(\@@)", $builddata) : AEBuild("$type(\@)", $builddata); # http://developer.apple.com/technotes/tn/tn2046.html my $stream = AEStream->new; $stream->WriteDesc($type, $packed); my $desc6 = $stream->Close; #diag("$type: $datum"); if ($datum eq $data->[-1]) { ok(AEPut($list, AECountItems($list)+1, $type, $packed), 'AEPut'); ok(AEPutKey($reco, $type, $type, $packed), 'AEPutKey'); ok(AEPutDesc($list2, AECountItems($list2)+1, $desc4), 'AEPutDesc'); ok(AEPutKeyDesc($reco2, $type, $desc4), 'AEPutKeyDesc'); ok($lists->WriteDesc($type, $packed), 'WriteDesc list'); ok($recos->WriteKeyDesc($type, $type, $packed), 'WriteKeyDesc record'); unless ($skip) { if ($lit) { $listg_fmt .= "$type($builddata), "; $recog_fmt .= "$type : $type($builddata), "; } else { my $at = $hand ? '@@' : '@'; $listg_fmt .= "$type($at), "; $recog_fmt .= "$type : $type($at), "; push @g_param, $builddata; } } } #diag("$type($builddata)"); #diag(AEPrint($desc4)); #diag(AEPrint($desc5)) if $desc5; for my $desc ($desc1, $desc2, $desc3, $desc4, $desc5, $desc6) { next unless $desc; CheckDesc($desc, $type, $datum); } } } # 14 s/, $// for ($listg_fmt, $recog_fmt); my $listg = AEBuild("[$listg_fmt]", @g_param); is($listg->type, typeAEList, 'Create AEList'); my $recog = AEBuild("{$recog_fmt}", @g_param); is($recog->type, typeAERecord, 'Create AERecord'); ok($lists->CloseList, 'CloseList'); ok($recos->CloseRecord, 'CloseRecord'); ok(my $list3 = $lists->Close, 'Close list'); ok(my $reco3 = $recos->Close, 'Close record'); my $count = scalar keys %types; for my $L ($list, $list2, $list3, $reco, $reco2, $reco3) { is(AECountItems($L), $count, 'Count list items'); } my $countg = $count - 5; for my $L ($listg, $recog) { is(AECountItems($L), $countg, 'Count list items'); } # 15 * 13 * 3 = 585, + 13 * 10 = 715 my $i = 0; my $g = 0; for my $type (sort keys %types) { $i++; $g++; my $datum = $types{$type}[-1]; #diag("AEList: $type: $datum"); my $j = 0; for my $L ($list, $list2, $list3, $listg) { my $k = $i; if (++$j == 4) { #diag("ok!: $type: $g"); if (SkipType($type)) { $g--; next; } $k = $g; } my $desc = AEGetNthDesc($L, $k); CheckDesc($desc, $type, $datum); } $j = 0; for my $L ($reco, $reco2, $reco3, $recog) { my $k = $i; if (++$j == 4) { #diag("ok!!: $type: $g"); if (SkipType($type)) { next; } $k = $g; } my $desc = AEGetKeyDesc($L, $type); CheckDesc($desc, $type, $datum); # same as above, but fetch by index ($desc, my($key)) = AEGetNthDesc($L, $k); is($key, $type, 'Check key'); CheckDesc($desc, $type, $datum); } } # 15 * 11 * 3 = 495 $i = 0; for my $type (sort keys %types) { $i++; my $datum = $types{$type}[-1]; #diag("AEDelete: $type: $datum"); for my $L ($list, $list2, $list3) { my $desc = AEGetNthDesc($L, 1); CheckDesc($desc, $type, $datum); AEDeleteItem($L, 1); my $tab = AECountItems($L); cmp_ok($tab, '==', $count-$i, 'Count items remaining'); } for my $L ($reco, $reco2, $reco3) { my($desc, $key) = AEGetNthDesc($L, 1); is($key, $type, 'Check key'); CheckDesc($desc, $type, $datum); AEDeleteItem($L, 1); my $tab = AECountItems($L); $tab =~ s/\D+//; is($tab, $count-$i, 'Count items remaining'); } } # 8 for my $L ($list, $list2, $list3, $listg, $reco, $reco2, $reco3, $recog) { ok(AEDisposeDesc($L), 'Dispose list'); } } SKIP: { # skip "AECoerce tests", 13+13+13; my $string = "abcdef"; my $desc = AEDesc->new(typeChar, $string); my $desc2 = AECoerceDesc($desc, typeUnicodeText); my $desc3 = AECoerce(typeChar, $string, typeUnicodeText); # 13 CheckDesc($desc, typeChar, $string); CheckRef($desc2, typeUnicodeText); CheckType($desc2, typeUnicodeText); is(length($desc2->get), 2*length($string), 'Length check'); CheckRef($desc3, typeUnicodeText); CheckType($desc3, typeUnicodeText); is(length($desc3->get), 2*length($string), 'Length check'); is($desc2->get, $desc3->get, 'Value check'); CheckDispose($desc2); CheckDispose($desc3); my $keyw = "abcd"; $desc = AEDesc->new(typeKeyword, $keyw); $desc2 = AECoerceDesc($desc, typeChar); $desc3 = AECoerce(typeKeyword, $keyw, typeChar); # 13 CheckDesc($desc, typeKeyword, $keyw); is($desc2->get, $desc3->get, 'Value check'); CheckDesc($desc2, typeChar, $keyw); CheckDesc($desc3, typeChar, $keyw); my $num = 2**18; my $num2 = $num + .45; $desc = AEDesc->new(typeFloat, MacPack(typeFloat, $num2)); $desc2 = AECoerceDesc($desc, typeInteger); $desc3 = AECoerce(typeFloat, MacPack(typeFloat, $num2), typeInteger); # 13 CheckDesc($desc, typeFloat, $num2); CheckRef($desc2, typeInteger); CheckType($desc2, typeInteger); is($desc2->get, $num, 'Value check'); CheckRef($desc3, typeInteger); CheckType($desc3, typeInteger); is($desc3->get, $num, 'Value check'); is($desc2->get, $desc3->get, 'Value check'); CheckDispose($desc2); CheckDispose($desc3); } sub MakeFourChar { pack "N", unpack "L", $_[0]; } sub MakeHex { '$' . join('', map { sprintf("%02X", ord) } split //, MakeFourChar($_[0])) . '$'; } sub MakeNumHex { my $hex = '$' . sprintf("%02X", $_[0]) . '$'; if (length($hex) % 2) { $hex =~ s/^\$/\$0/; } return $hex; } sub SkipType { my($type) = @_; return 1 if $type eq typeShortFloat || $type eq typeFloat || $type eq typeMagnitude || $type eq typeQDRectangle || $type eq typeRGBColor; return 0; } =pod =head1 TODO =over 4 * location/range/comparison/logical? * AEBuild doesn't work with unsigned 32-bit or floats? * AEBuild doesn't automatically handle byteswapping of OSTypes * AEStream WriteData, same problem =back __END__
#!/usr/bin/perl use warnings; use strict; use FindBin '$Bin'; use Test::More tests => 1+(42+15)+(37+5)+(4+41+19)+(47*3); BEGIN { use_ok('Mac::AppleEvents'); require "$Bin/helper.pl"; } use File::Spec::Functions qw(catdir tmpdir); use Mac::Files; use Mac::Types; my $name = 'mac-carbon-aeevent-test'; my $file = catdir(tmpdir(), $name); my $filehex = MakeHexUTF16($name); my $newname = 'mac-carbon-aeevent-test2'; my $newfile = $file . '2'; END { # unlink $file; # unlink $newfile; } SKIP: { # skip "AECreateAppleEvent", 42+15+47; ## reveal file 4+1+15+20+2=42 # 4 my $target = AEDesc->new(typeApplSignature, 'MACS'); CheckRefType($target, typeApplSignature); # misc/mvis = reveal my $event = AECreateAppleEvent('misc', 'mvis', $target); CheckRefType($event, typeAppleEvent); # 1 { open my $fh, '>', $file or die $!; print $fh "testing\n"; } ok(-e $file, 'Check test file exists'); # 15 my $alias = NewAliasMinimalFromFullPath($file); is(ref $alias, 'Handle', 'Check Handle ref type'); my $aliasdesc = AEDesc->new(typeAlias, $alias); CheckRefType($aliasdesc, typeAlias); ok(AEPutParamDesc($event, keyDirectObject, $aliasdesc), 'AEPutParamDesc'); CheckDispose($aliasdesc); my $reply = AESend($event, kAEWaitReply); CheckSuccess($event, $reply); my $filedesc = AEGetParamDesc($reply, keyDirectObject); CheckRefType($filedesc, typeObjectSpecifier); # 20 CheckAttributes($event, $reply, qw(misc mvis MACS)); # 2 CheckDispose($event); CheckDispose($reply); ## change file name 2+2+11=15 # 2 $event = AECreateAppleEvent('core', 'setd', $target); CheckRefType($event, typeAppleEvent); # 2 my $filenamedesc = AECreateList('', 1); CheckRefType($filenamedesc, typeAERecord); # 11 ok(AEPutKey ($filenamedesc, keyAEForm, typeEnumerated, typeProperty), 'AEPutKey'); ok(AEPutKey ($filenamedesc, keyAEDesiredClass, typeType, typeProperty), 'AEPutKey'); ok(AEPutKeyDesc($filenamedesc, keyAEContainer, $filedesc), 'AEPutKeyDesc'); ok(AEPutKey ($filenamedesc, keyAEKeyData, typeType, 'pnam'), 'AEPutKey'); # name my $obj = AECoerceDesc($filenamedesc, typeObjectSpecifier); CheckRefType($obj, typeObjectSpecifier); CheckDispose($filenamedesc); ok(AEPutParamDesc($event, keyDirectObject, $obj), 'AEPutParamDesc'); ok(AEPutParam($event, 'data', typeChar, $newname), 'AEPutParam'); CheckDispose($obj); CheckDispose($target); Finish($event); } SKIP: { # skip "AEBuildAppleEvent", 37+5+47; ## reveal file 2+1+12+20+2=37 # 2 # misc/mvis = reveal my $event = AEBuildAppleEvent('misc', 'mvis', typeApplSignature, 'MACS', kAutoGenerateReturnID, kAnyTransactionID, ''); CheckRefType($event, typeAppleEvent); # 1 { open my $fh, '>', $file or die $!; print $fh "testing\n"; } ok(-e $file, 'Check test file exists'); # 12 my $alias = NewAliasMinimalFromFullPath($file); is(ref $alias, 'Handle', 'Check Handle ref type'); ok(AEBuildParameters($event, q"'----':alis(@@)", $alias), 'AEBuildParameters'); my $reply = AESend($event, kAEWaitReply); CheckSuccess($event, $reply); my $filedesc = AEGetParamDesc($reply, keyDirectObject); CheckRefType($filedesc, typeObjectSpecifier); # 20 CheckAttributes($event, $reply, qw(misc mvis MACS)); # 2 CheckDispose($event); CheckDispose($reply); ## change file name 2+3=5 # 2 $event = AEBuildAppleEvent('core', 'setd', typeApplSignature, 'MACS', kAutoGenerateReturnID, kAnyTransactionID, ''); CheckRefType($event, typeAppleEvent); # 3 my $filedesc_print = AEPrint($filedesc); like($filedesc_print, qr/^'obj '/, 'AEPrint'); #diag($filedesc_print); # Apple bugs ... really, since the format of AEPrint can change, # this might be a bad way to do the tests, but I'll worry about it # when it breaks ... for now, I just need to get it done, and besides, # this helped me identify some bugs in AEPrint $filedesc_print =~ s/''null''/'null'/g; $filedesc_print =~ s/'want':'(\w+)'/'want':type($1)/g; $filedesc_print =~ s/'seld':'sdsk'/'seld':type(sdsk)/g; #diag($filehex); while ($filedesc_print =~ /\(\$(.+?)\$\)/g) { my $x = my $y = $1; $x =~ s/[^A-F0-9]+//g; #diag($x); next unless $filehex =~ /^\Q$x\E/; #diag('!!'); if ($x ne $y) { $filedesc_print =~ s/'utxt'\(\$$y\$\)/'TEXT'(\@)/; } } #diag($filedesc_print); my $fmt = "'----':'obj '{ 'form':'prop', 'want':type(prop), 'from':$filedesc_print, 'seld':type(pnam) }"; # $fmt = q"'----':'obj '{ 'form':prop, 'want':type(prop), 'from':'obj '{ 'want':type(docf), 'from':'obj '{ 'want':type(cfol), 'from':'obj '{ 'want':type(cobj), 'from':'obj '{ 'want':type(prop), 'from':'null'(), 'form':prop, 'seld':type(sdsk) }, 'form':name, 'seld':'utxt'($0070007200690076006100740065$) }, 'form':name, 'seld':'utxt'($0074006D0070$) }, 'form':name, 'seld':'TEXT'(@) }, 'seld':type(pnam) }"; #diag($fmt); ok(AEBuildParameters($event, $fmt, 'mac-carbon-aeevent-test'), 'AEBuildParameters'); #diag($@); ok(AEBuildParameters($event, 'data:TEXT(@)', $newname), 'AEBuildParameters'); #diag(AEPrint($event)); Finish($event); } SKIP: { # skip "AEStream", 4+41+19+47; ## Quick Abort check 4 ok(my $stream_abort = AEStream->new, 'AEStream->new/Open'); ok($stream_abort->OpenDesc(typeInteger), 'OpenDesc'); ok($stream_abort->WriteData(12334567890), 'WriteData'); is($stream_abort->Abort, 0, 'Abort!'); ## reveal file 3+1+15+20+2=41 # 3 # misc/mvis = reveal # OpenEvent my $event1 = AEBuildAppleEvent('misc', 'mvis', typeApplSignature, 'MACS', kAutoGenerateReturnID, kAnyTransactionID, ''); CheckRefType($event1, typeAppleEvent); ok(my $stream = AEStream->new($event1), 'AEStream->new/OpenEvent'); # 1 { open my $fh, '>', $file or die $!; print $fh "testing\n"; } ok(-e $file, 'Check test file exists'); # 16 my $alias = NewAliasMinimalFromFullPath($file); is(ref $alias, 'Handle', 'Check Handle ref type'); ok($stream->WriteKey(keyDirectObject), 'WriteKey keyDirectObject'); ok($stream->OpenDesc(typeAlias), 'OpenDesc typeAlias'); ok($stream->WriteData($alias->get), 'WriteData alias'); ok($stream->CloseDesc, 'CloseDesc'); my $event = $stream->Close; CheckRefType($event, typeAppleEvent); my $reply = AESend($event, kAEWaitReply); CheckSuccess($event, $reply); my $filedesc = AEGetParamDesc($reply, keyDirectObject); CheckRefType($filedesc, typeObjectSpecifier); # 20 CheckAttributes($event, $reply, qw(misc mvis MACS)); # 2 CheckDispose($event); CheckDispose($reply); ## change file name 19 # CreateEvent ok($stream = AEStream->new('core', 'setd', typeApplSignature, 'MACS'), 'AEStream->new/CreateEvent'); ok($stream->WriteKey(keyDirectObject), 'WriteKey direct object'); ok($stream->OpenRecord(typeLogicalDescriptor), 'OpenRecord logical typeLogicalDescriptor'); ok($stream->WriteKeyDesc(keyAEForm, typeEnumerated, typeProperty), 'WriteKeyDesc form prop'); ok($stream->WriteKeyDesc(keyAEDesiredClass, typeType, typeProperty), 'WriteKeyDesc want prop'); ok($stream->WriteKey(keyAEContainer), 'WriteKeyDesc from'); ok($stream->WriteAEDesc($filedesc), 'WriteAEDesc from'); ok($stream->WriteKeyDesc(keyAEKeyData, typeType, 'pnam'), 'WriteKeyDesc seld pnam'); ok($stream->SetRecordType(typeObjectSpecifier), 'SetRecordType keyDirectObject'); ok($stream->CloseRecord, 'CloseRecord'); ok($stream->OpenKeyDesc('data', typeChar), 'OpenKeyDesc data typeChar'); ok($stream->WriteData($newname), 'WriteData name'); ok($stream->CloseDesc, 'CloseDesc'); ok($stream->WriteKeyDesc('doof', typeChar, 'floobydoo!'), 'WriteKeyDesc for optional'); ok($stream->OptionalParam('doof'), 'OptionalParam'); $event = $stream->Close; CheckRefType($event, typeAppleEvent); Finish($event); } # 6+11+28+2=47 sub Finish { my($event) = @_; # 6 ok(AEPutAttribute($event, keyOptionalKeywordAttr, typeInteger, MacPack(typeInteger, 1)), 'AEPutAttribute'); my $vers = 'version .129381231'; my $miss = AEDesc->new(typeChar, $vers); ok(AEPutAttributeDesc($event, keyAEVersion, $miss), 'AEPutAttributeDesc'); CheckDesc($miss, typeChar, $vers); # 11 my $reply = AESend($event, kAEWaitReply); CheckSuccess($event, $reply); is(AECountItems($reply), 1, 'Count reply'); ok(AEDeleteParam($reply, keyDirectObject), 'Delete reply'); cmp_ok(AECountItems($reply), '==', 0, 'Count reply'); # 28 CheckAttributes($event, $reply, qw(core setd MACS)); CheckAttribute($event, keyOptionalKeywordAttr, typeInteger, 1); CheckAttribute($event, keyAEVersion, typeChar, $vers); # 2 CheckDispose($event); CheckDispose($reply); unlink $file; unlink $newfile; } # 8 sub CheckSuccess { my($event, $reply) = @_; CheckRefType($event, typeAppleEvent); CheckRefType($reply, typeAppleEvent); my $errn = AEGetParamDesc($reply, keyErrorNumber); cmp_ok($!, '==', -1701, 'No error'); my $errs = AEGetParamDesc($reply, keyErrorString); cmp_ok($!, '==', -1701, 'No error'); for my $err ($errn, $errs) { if ($err) { is($err->get, 0, 'Error?'); } else { pass('Still no error'); } } #diag(AEPrint($event)); #diag(AEPrint($reply)); } # 4 sub CheckAttribute { my($event, $key, $type, $val) = @_; my $desc = AEGetAttributeDesc($event, $key, $type); CheckDesc($desc, $type, $val); } # 20 sub CheckAttributes { my($event, $reply, @vals) = @_; CheckAttribute($event, keyEventClassAttr, typeType, $vals[0]); CheckAttribute($event, keyEventIDAttr, typeChar, $vals[1]); # for fun CheckAttribute($event, keyAddressAttr, typeApplSignature, $vals[2]); CheckAttribute($reply, keyEventClassAttr, typeChar, 'aevt'); CheckAttribute($reply, keyEventIDAttr, typeType, 'ansr'); } sub MakeHexUTF16 { use Config; my $fmt = $Config{byteorder} == 4321 ? '00%02X' : '%02X00'; join('', map { sprintf($fmt, ord) } split //, $_[0]); } __END__