use strict; use warnings; use constant DONE => 1; # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More qw(no_plan); use Data::Dumper; $Data::Dumper::Indent = 1; sub _chomp { my $s = shift; chomp $s; return $s; } use TM; use TM::PSI; sub _parse { my $text = shift; my $ms = new TM (baseuri => 'tm:'); use TM::CTM::Parser; my $p = new TM::CTM::Parser (store => $ms); my $i = $p->parse ($text); return $ms; } sub die_ok { my $ctm = shift; my $err = shift; eval { _parse ($ctm); fail ("exc: expected $@"); }; chomp ($@); my $verr = $@; $verr =~ s/\n/\n /g; # create blanks/comments on multiline complaints like ($@, qr/$err/, "exc: found '$verr'"); } sub _q_players { my $ms = shift; my @res = $ms->match (TM->FORALL, @_); # warn "res no filter ".Dumper \@res; @res = grep ($_ !~ m|^tm:|, map { ref($_) ? ${$_} : $_ } map { @{$_->[TM->PLAYERS]} } $ms->match (TM->FORALL, @_)); # warn "res ".Dumper \@res; return \@res; } my $warn = shift @ARGV; unless ($warn) { close STDERR; open (STDERR, ">/dev/null"); select (STDERR); $| = 1; } #== TESTS =========================================================================== my $npa = scalar keys %{$TM::infrastructure->{assertions}}; my $npt = scalar keys %{$TM::infrastructure->{mid2iid}}; if (DONE) { # 3.2.1. Topic with an Item Identifier my $ms = _parse (q| john. |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.2.1. Topic with an Item Identifier'); is ($ms->toplets, $npt+1, ' one additional'); } if (DONE) { # 3.2.2. Typed Topic - Using Item Identifiers my $ms = _parse (q| john isa person. |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.2.2. Typed Topic - Using Item Identifiers'); ok ($ms->tids ('person'), '3.2.2. Typed Topic - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); ok (eq_set ([ $ms->instances ('tm:person') ], [ 'tm:john' ]), ' instances'); } if (DONE) { # 3.2.3. Typed Topic - Using Subject Identifiers my $ms = _parse (q| john isa http://psi.example.org/music/guitarist. paul isa http://psi.example.org/music/guitarist . george isa http://psi.example.org/music/guitarist . |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.2.3. Typed Topic - Using Subject Identifiers'); ok ($ms->tids ('paul'), '3.2.3. Typed Topic - Using Subject Identifiers'); ok ($ms->tids ('george'), '3.2.3. Typed Topic - Using Subject Identifiers'); is ($ms->toplets, $npt+4, ' additional'); ok (eq_set ([ $ms->types ('tm:john') ], [ 'tm:uuid-0000000000' ]), ' types'); ok (eq_set ($ms->toplet ('tm:uuid-0000000000')->[TM->INDICATORS], [ 'http://psi.example.org/music/guitarist' ]), ' indicators'); ok (eq_set ([ $ms->instances ('tm:uuid-0000000000') ], [ 'tm:john', 'tm:paul', 'tm:george' ] ), ' instances'); } if (DONE) { # 3.2.3. Typed Topic - Using Subject Identifiers, using the "prefix" directive my $ms = _parse (q| %prefix music http://psi.example.org/music/ john isa music:guitarist. paul isa music:guitarist . george isa music:guitarist . |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.2.3. Typed Topic - Using Subject Identifiers, prefixed'); ok ($ms->tids ('paul'), '3.2.3. Typed Topic - Using Subject Identifiers, prefixed'); ok ($ms->tids ('george'), '3.2.3. Typed Topic - Using Subject Identifiers, prefixed'); is ($ms->toplets, $npt+4, ' additional'); my $guitarman = $ms->mids (\ 'http://psi.example.org/music/guitarist'); ok (eq_set ($ms->toplet ($guitarman)->[TM->INDICATORS], [ 'http://psi.example.org/music/guitarist' ]), ' indicators'); ok (eq_set ([ $ms->instances ($guitarman) ], [ 'tm:john', 'tm:paul', 'tm:george' ]), ' instances'); } if (DONE) { # 3.2.4. Multityped Topic - Using Item Identifiers my $ms = _parse (q| john isa singer; isa guitarist. |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.2.4. Multityped Topic - Using Item Identifiers'); ok ($ms->tids ('singer'), '3.2.4. Multityped Topic - Using Item Identifiers'); ok ($ms->tids ('guitarist'), '3.2.4. Multityped Topic - Using Item Identifiers'); is ($ms->toplets, $npt+3, ' additional'); ok (eq_set ([ $ms->instances ('tm:singer') ], [ 'tm:john' ]), ' instances'); ok (eq_set ([ $ms->instances ('tm:guitarist') ], [ 'tm:john' ]), ' instances'); } if (DONE) { # 3.2.5. Multityped Topic - Using Subject Identifiers my $ms = _parse (q| http://psi.example.org/beatles/john isa singer; isa guitarist. |); #warn Dumper $ms; my $john = $ms->tids (\ 'http://psi.example.org/beatles/john'); ok ($john, '3.2.5. Multityped Topic - Using Subject Identifiers'); ok ($ms->tids ('singer'), '3.2.5. Multityped Topic - Using Subject Identifiers'); ok ($ms->tids ('guitarist'), '3.2.5. Multityped Topic - Using Subject Identifiers'); is ($ms->toplets, $npt+3, ' additional'); ok (eq_set ([ $ms->instances ('tm:singer') ], [ $john ]), ' instances'); ok (eq_set ([ $ms->instances ('tm:guitarist') ], [ $john ]), ' instances'); } if (DONE) { # 3.3.1. Topic with an Item Identifier and Topic Name my $ms = _parse (q| john - "John Lennon". |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.3.1. Topic with an Item Identifier and Topic Name'); is ($ms->toplets, $npt+1, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $ms->tids ('john')) ] , [ 'John Lennon' ]), ' names of john'); } if (DONE) { # 3.3.2. Topic with a Subject Identifier and Topic Name my $ms = _parse (q| %prefix beatles http://psi.beatles.example.org/ beatles:john - "John Lennon" . |); #warn Dumper $ms; my $john = $ms->tids (\ 'http://psi.beatles.example.org/john' ); ok ($john, '3.3.2. Topic with a Subject Identifier and Topic Name'); is ($ms->toplets, $npt+1, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $john) ] , [ 'John Lennon' ]), ' names of john'); } if (DONE) { # 3.3.3. Topic with a Subject Locator and a Topic Name my $ms = _parse (q| = http://beatles.com/ - "Official website of The Beatles". |); #warn Dumper $ms; my $beatles = $ms->tids ( 'http://beatles.com/' ); ok ($beatles, '3.3.3. Topic with a Subject Locator and a Topic Name'); is ($ms->toplets, $npt+1, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $beatles) ] , [ 'Official website of The Beatles' ]), ' name of beatles'); } if (DONE) { # 3.3.4. Typed Topic Name - Using Item Identifiers my $ms = _parse (q| john - fullname: "John Ono Lennon". |); #warn Dumper $ms; my $john = $ms->tids ( 'john' ); ok ($john, '3.3.4. Typed Topic Name - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:fullname'} $ms->match_forall (char => 1, topic => $john) ] , [ 'John Ono Lennon' ]), ' fullname of john'); ok (eq_set ([ map { $_->[TM->TYPE] } $ms->retrieve ( $ms->instances ('name') ) ] , [ 'tm:fullname' ]), ' fullname of john (name subtype)'); } if (DONE) { # 3.3.5. Typed Topic Names - Using Subject Identifiers my $ms = _parse (q| john - http://psi.example.org/fullname: "John Ono Lennon". |); #warn Dumper $ms; my $john = $ms->tids ( 'john' ); ok ($john, '3.3.5. Typed Topic Names - Using Subject Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my $fn = $ms->tids (\ 'http://psi.example.org/fullname'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq $fn } $ms->match_forall (char => 1, topic => $john) ] , [ 'John Ono Lennon' ]), ' fullname of john'); ok (eq_set ([ map { $_->[TM->TYPE] } $ms->retrieve ( $ms->instances ('name') ) ] , [ $fn ]), ' fullname of john (name subtype)'); } if (DONE) { # 3.3.6. Scoped Topic Name - Using Item Identifiers my $ms = _parse (q| john - "John Ono Lennon" @fullname. |); #warn Dumper $ms; my $john = $ms->tids ( 'john' ); ok ($john, '3.3.6. Scoped Topic Name - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->SCOPE] eq 'tm:fullname' } grep { $_->[TM->TYPE] eq 'name' } $ms->match_forall (char => 1, topic => $john) ] , [ 'John Ono Lennon' ]), ' name of john (scoped)'); ok (eq_set ([ $ms->instances ('scope') ] , [ 'tm:fullname', 'us' ]), ' fullname of john isa scope'); } if (DONE) { # 3.3.7. Scoped Topic Name - Using Subject Itentifiers my $ms = _parse (q| %prefix ex http://blabla.org/ john - "John Ono Lennon" @ex:fullname. |); #warn Dumper $ms; my $john = $ms->tids ( 'john' ); ok ($john, '3.3.7. Scoped Topic Name - Using Subject Itentifiers'); my $fn = $ms->tids (\ 'http://blabla.org/fullname'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->SCOPE] eq $fn } grep { $_->[TM->TYPE] eq 'name' } $ms->match_forall (char => 1, topic => $john) ] , [ 'John Ono Lennon' ]), ' name of john (scoped)'); ok (eq_set ([ $ms->instances ('scope') ] , [ $fn, 'us' ]), ' fullname of john isa scope'); } if (DONE) { # 3.3.8. Multi Scoped Topic Name eval { my $ms = _parse (q| %prefix ex http://blabla.org/ beatles - "The Beatles"; - "Fab Four" @nickname short . |); }; like ($@, qr/unparseable/, 'multipled scopes NOT supported here'); } if (DONE) { # 3.3.9. Typed and Scoped Names my $ms = _parse (q| john - fullname: "John Ono Lennon" @yoko. |); #warn Dumper $ms; my $john = $ms->tids ( 'john' ); ok ($john, ' 3.3.9. Typed and Scoped Names'); is ($ms->toplets, $npt+3, ' additional'); is ($ms->asserts, $npa+3, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->SCOPE] eq 'tm:yoko' } grep { $_->[TM->TYPE] eq 'tm:fullname' } $ms->match_forall (char => 1, topic => $john) ] , [ 'John Ono Lennon' ]), ' name of john (scoped)'); ok (eq_set ([ $ms->subclasses ('name') ] , [ 'tm:fullname' ]), ' fullname of john ako name'); ok (eq_set ([ $ms->instances ('scope') ] , [ 'tm:yoko', 'us' ]), ' fullname of john isa scope'); } if (DONE) { # 3.3.10. Topic Name with Variant of datatype String eval { my $ms = _parse (q| john - "John Lennon" ("lennon, john" @tm:sort). |); }; like ($@, qr/unparseable/, 'variants NOT supported here'); } if (DONE) { # 3.3.11. Topic Name with Variant of datatype XML eval { my $ms = _parse (q| john - "John Lennon" ( "John Lennon"^^xsd:anyType @markup). |); }; like ($@, qr/unparseable/, 'variants NOT supported here'); } if (DONE) { # 3.3.12. Topic Name with Variant of datatype URI eval { my $ms = _parse (q| john - "John Lennon" (http://link/to/an/image.jpg @image). |); }; like ($@, qr/unparseable/, 'variants NOT supported here'); } if (DONE) { # 3.3.13. Topic Name with Variant with non-TMDM datatype eval { my $ms = _parse (q| revolution-nine - "Revolution No. 9" (9 @number). |); }; like ($@, qr/unparseable/, 'variants NOT supported here'); } if (DONE) { # template-simple my $ms = _parse (q| def template () topic. topic2 . created (person : mccartney, song : yesterday) end template() |); ok ($ms->mids ('topic'), 'template-simple'); ok ($ms->mids ('topic2'), ' 2. topic'); ok (eq_array ([ map { @{ $_->[TM->PLAYERS] } } grep { $_->[TM->TYPE] eq 'tm:created' } $ms->match_forall (iplayer => 'tm:yesterday') ], [ 'tm:mccartney', 'tm:yesterday' ]), ' template-simple: players'); } if (DONE) { # templates with parameters my $ms = _parse (q| def has-shoesize($person, $size) $person shoesize: $size. end has-shoesize (aaa, 42) has-shoesize (bbb, 43) |); ok (1, 'template params'); ok ($ms->mids ('aaa'), ' aaa'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $ms->tids ('aaa')) ] , [ '42' ]), ' shoesize aaa'); ok ($ms->mids ('bbb'), ' bbb'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $ms->tids ('bbb')) ] , [ '43' ]), ' shoesize bbb'); is ($ms->toplets, $npt+3, ' additional'); is ($ms->asserts, $npa+3, ' additional'); } if (DONE) { eval { my $ms = _parse (q| def template() topic . end def template () topic2. end |); }; like ($@, qr/template.*defined/, 'templates: double defed'); } if (DONE) { eval { my $ms = _parse (q| def template () topic. end templtae() |); }; like ($@, qr/unparseable/, 'templates: undefed'); } if (DONE) { eval { my $ms = _parse (q| def template ($a, $b) topic. end template(23) |); }; like ($@, qr/too few/, 'templates: too few arguments'); } if (DONE) { eval { my $ms = _parse (q| def template ($a, $b) topic. end template(23, aaa, bbb) |); }; like ($@, qr/too many/, 'templates: too many arguments'); } if (DONE) { #-- topic template invocation my $ms = _parse (q| def has-shoesize($person, $size) $person shoesize: $size. end def is-member-of($member, $group) is-member-of(member: $member, group: $group) end http://psi.example.org/beatles/paul isa person; has-shoesize(45); is-member-of(the-beatles); homepage: http://www.paulmccartney.com/ . |); ok (1, 'topic template invocation'); my $t = $ms->mids (\ 'http://psi.example.org/beatles/paul'); ok ($t, ' paul'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:shoesize' } $ms->match_forall (char => 1, topic => $ms->tids ($t)) ] , [ '45' ]), ' shoesize paul'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:homepage' } $ms->match_forall (char => 1, topic => $ms->tids ($t)) ] , [ 'http://www.paulmccartney.com/' ]), ' homepage paul'); ok (eq_array ([ map { @{ $_->[TM->PLAYERS] } } grep { $_->[TM->TYPE] eq 'tm:is-member-of' } $ms->match_forall (iplayer => $t) ], [ 'tm:the-beatles', $t ]), ' players'); is ($ms->toplets, $npt+8, ' additional'); is ($ms->asserts, $npa+6, ' additional'); } if (DONE) { my $ms = _parse (q| topic occtype: "Occurrence" ~ [ - "reifier"]. |); #warn Dumper $ms; ok ($ms->mids ('topic'), 'embedding topic'); my @oc = $ms->match_forall (char => 1, topic => $ms->tids ('topic')); is (scalar @oc, 1, ' only one occ'); is ($oc[0]->[TM->TYPE], 'tm:occtype', ' occtype'); my ($re) = $ms->is_reified ($oc[0]); like ($re, qr/uuid-\d{10}/, ' generated topic'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $re) ] , [ 'reifier' ]), ' name of reifier'); } if (DONE) { # 3.4.2. Typed Occurrence of datatype String - Using Item Identifiers my $ms = _parse (q| a-day-in-the-life lyrics: "I read ...". |); #warn Dumper $ms; ok ('tm:a-day-in-the-life', ' 3.4.2. Typed Occurrence of datatype String - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:lyrics' } $ms->match_forall (char => 1, topic => 'tm:a-day-in-the-life') ] , [ 'I read ...' ]), ' occ types'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:lyrics' ]), ' lyrics ako occurrence'); } if (DONE) { # 3.4.3. Typed Occurrence of datatype String - Using Subject Identifiers my $ms = _parse (q| %prefix ex http://www.blabla.org/ a-day-in-the-life ex:lyrics: "I read ...". |); #warn Dumper $ms; ok ('tm:a-day-in-the-life', ' 3.4.2. Typed Occurrence of datatype String - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq $ms->tids (\ 'http://www.blabla.org/lyrics') } $ms->match_forall (char => 1, topic => 'tm:a-day-in-the-life') ] , [ 'I read ...' ]), ' occ types'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ $ms->tids (\ 'http://www.blabla.org/lyrics') ]), ' lyrics ako occurrence'); } if (DONE) { # 3.4.4. Scoped Occurrence of datatype String - Using Item Identifiers my $ms = _parse (q| a-day-in-the-life lyrics: "I read ..." @en. |); #warn Dumper $ms; ok ('tm:a-day-in-the-life', '3.4.4. Scoped Occurrence of datatype String - Using Item Identifiers'); is ($ms->toplets, $npt+3, ' additional'); is ($ms->asserts, $npa+3, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->SCOPE] eq 'tm:en' } grep { $_->[TM->TYPE] eq 'tm:lyrics' } $ms->match_forall (char => 1, topic => 'tm:a-day-in-the-life') ] , [ 'I read ...' ]), ' occ types'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:lyrics' ]), ' lyrics ako occurrence'); ok (eq_set ([ $ms->instances ('scope') ] , [ 'tm:en', 'us' ]), ' en isa scope'); } if (DONE) { # 3.4.5. Scoped Occurrence of datatype String - Using Subject Identifiers my $ms = _parse (q| %prefix ex http://bla.org/ %prefix lang http://language.org a-day-in-the-life ex:lyrics: "I read ..." @lang:en. |); #warn Dumper $ms; ok ('tm:a-day-in-the-life', '3.4.4. Scoped Occurrence of datatype String - Using Item Identifiers'); is ($ms->toplets, $npt+3, ' additional'); is ($ms->asserts, $npa+3, ' additional'); ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->SCOPE] eq $ms->tids (\ 'http://language.orgen') } grep { $_->[TM->TYPE] eq $ms->tids (\ 'http://bla.org/lyrics') } $ms->match_forall (char => 1, topic => 'tm:a-day-in-the-life') ] , [ 'I read ...' ]), ' occ types'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ $ms->tids (\ 'http://bla.org/lyrics') ]), ' lyrics ako occurrence'); ok (eq_set ([ $ms->instances ('scope') ] , [ $ms->tids (\ 'http://language.orgen'), 'us' ]), ' en isa scope'); } if (DONE) { # 3.4.6. Occurrence of datatype XML my $ms = _parse (q| a-day-in-the-life lyrics: """
[...] [...] """^^xsd:anyType. |); #warn Dumper $ms; ok ('tm:a-day-in-the-life', '3.4.6. Occurrence of datatype XML'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); # ok (eq_set ([ map { $_->[0] } my ($v) = map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:lyrics' } $ms->match_forall (char => 1, topic => 'tm:a-day-in-the-life'); like ($v->[0], qr/.*html>/s, ' XML value'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:lyrics' ]), ' lyrics ako occurrence'); } if (DONE) { # 3.4.7. Occurrence of datatype IRI my $ms = _parse (q| beatles website: http://www.beatles.com/ . |); #warn Dumper $ms; ok ('tm:beatles', '3.4.7. Occurrence of datatype IRI'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my ($v) = map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:website' } $ms->match_forall (char => 1, topic => 'tm:beatles'); is ($v->[0], 'http://www.beatles.com/', ' value'); is ($v->[1], TM::Literal->URI, ' datatype'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:website' ]), ' website ako occurrence'); } if (DONE) { # 3.4.7. Occurrence of datatype IRI, explict my $ms = _parse (q| beatles website: "http://www.beatles.com/"^^xsd:anyURI. |); #warn Dumper $ms; ok ('tm:beatles', '3.4.7. Occurrence of datatype IRI, explicit'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my ($v) = map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:website' } $ms->match_forall (char => 1, topic => 'tm:beatles'); is ($v->[0], 'http://www.beatles.com/', ' value'); is ($v->[1], TM::Literal->URI, ' datatype'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:website' ]), ' website ako occurrence'); } if (DONE) { # 3.4.8. Occurrence of non-TMDM datatype my $ms = _parse (q| pennylane track-number: 2. |); #warn Dumper $ms; ok ('tm:pennylane', '3.4.8. Occurrence of non-TMDM datatype'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my ($v) = map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:track-number' } $ms->match_forall (char => 1, topic => 'tm:pennylane'); is ($v->[0], '2', ' value'); is ($v->[1], TM::Literal->INTEGER, ' datatype'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:track-number' ]), ' website ako occurrence'); } if (DONE) { # 3.4.8. Occurrence of non-TMDM datatype, explicit my $ms = _parse (q| pennylane track-number: "2"^^xsd:integer. |); #warn Dumper $ms; ok ('tm:pennylane', '3.4.8. Occurrence of non-TMDM datatype, explicit'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my ($v) = map { $_->[TM->PLAYERS]->[1] } grep { $_->[TM->TYPE] eq 'tm:track-number' } $ms->match_forall (char => 1, topic => 'tm:pennylane'); is ($v->[0], '2', ' value'); is ($v->[1], TM::Literal->INTEGER, ' datatype'); ok (eq_set ([ $ms->subclasses ('occurrence') ] , [ 'tm:track-number' ]), ' website ako occurrence'); } if (DONE) { for (q| created(person : mccartney, song : yesterday) |, q| def created($creator, $song) created(person : $creator, song : $song) end mccartney created(yesterday). |, q| def created($creator, $song) created(person : $creator, song : $song) end created(mccartney, yesterday) | ) { # 3.5.1. Creating Associations my $ms = _parse ($_); #warn Dumper $ms; ok ('tm:created', '3.5.1. Creating Associations'); ok ('tm:mcartney', '3.5.1. Creating Associations'); is ($ms->toplets, $npt+5, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_array ([ map { @{ $_->[TM->PLAYERS] } } grep { $_->[TM->TYPE] eq 'tm:created' } $ms->match_forall (iplayer => 'tm:yesterday') ], [ 'tm:mccartney', 'tm:yesterday' ]), ' players'); } } if (DONE) { # 3.5.2. Scoped Association my $ms = _parse (q| created(person : mccartney, song : yesterday) @music |); #warn Dumper $ms; ok ('tm:created', '3.5.2. Scoped Association'); ok ('tm:mcartney', '3.5.2. Scoped Association'); is ($ms->toplets, $npt+6, ' additional'); is ($ms->asserts, $npa+2, ' additional'); ok (eq_array ([ map { @{ $_->[TM->PLAYERS] } } grep { $_->[TM->SCOPE] eq 'tm:music' } grep { $_->[TM->TYPE] eq 'tm:created' } $ms->match_forall (iplayer => 'tm:yesterday') ], [ 'tm:mccartney', 'tm:yesterday' ]), ' players'); ok (eq_set ([ $ms->instances ('scope') ] , [ 'tm:music', 'us' ]), ' music isa scope'); } if (DONE) { # 3.5.5. Supertype-Subtype relationship - Using Item Identifiers my $ms = _parse (q| song ako musical-work. |); #warn Dumper $ms; ok ('tm:song', '3.5.5. Supertype-Subtype relationship - Using Item Identifiers'); ok ('tm:musical-work', '3.5.5. Supertype-Subtype relationship - Using Item Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_set ([ $ms->subclasses ('tm:musical-work') ] , [ 'tm:song' ]), ' ako'); } if (DONE) { # 3.5.6. Supertype-Subtype relationship - Using Subject Identifiers my $ms = _parse (q| %prefix ex http://something/ ex:song ako ex:musical-work. |); #warn Dumper $ms; my $song = $ms->tids (\ 'http://something/song'); my $work = $ms->tids (\ 'http://something/musical-work'); ok ($song, '3.5.6. Supertype-Subtype relationship - Using Subject Identifiers'); ok ($work, '3.5.6. Supertype-Subtype relationship - Using Subject Identifiers'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+1, ' additional'); ok (eq_set ([ $ms->subclasses ($work) ] , [ $song ]), ' ako'); } if (DONE) { # 3.6.1 Reification of a Topic Map TODO: { local $TODO = "reification of map"; eval { my $ms = _parse (q| ~ [- "Beatlestopicmap"] |); }; ok (0); } } if (DONE) { # 3.6.2. Reification of a Topic Name my $ms = _parse (q| john - "John Ono Lennon" ~ name-of-john-lennon. |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.6.2. Reification of a Topic Name'); ok ($ms->tids ('name-of-john-lennon'), '3.6.2. Reification of a Topic Name'); is ($ms->toplets, $npt+2, ' additional'); is ($ms->asserts, $npa+1, ' additional'); my $a = $ms->reifies ('tm:name-of-john-lennon'); is ($a->[TM->KIND], TM->NAME, ' reified name'); is (($ms->is_reified ($a))[0], 'tm:name-of-john-lennon', ' reifying topic'); } if (DONE) { # 3.6.3. Reification of a Variant TODO: { local $TODO = "reification of variant"; eval { my $ms = _parse (q| john - "John Ono Lennon" ("lennon, john" @sort ~ sortname-of-john-lennon). |); }; ok (0); } } if (DONE) { # 3.6.4. Reification of a Occurrence my $ms = _parse (q| john website: http://www.lennon.com/ ~ lennons-website. |); #warn Dumper $ms; ok ($ms->tids ('john'), '3.6.4. Reification of a Occurrence'); ok ($ms->tids ('lennons-website'), '3.6.4. Reification of a Occurrence'); is ($ms->toplets, $npt+3, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my $a = $ms->reifies ('tm:lennons-website'); is ($a->[TM->KIND], TM->OCC, ' reified occ'); is (($ms->is_reified ($a))[0], 'tm:lennons-website', ' reifying topic'); } for (q| partnership(person: lennon, person: mc-cartney) ~ lennon-mccartney lennon-mccartney - "Lennon / McCartney". |, #q| # partnership(person: lennon, person: mc-cartney) ~ [- "Lennon / McCartney"] #| ) { if (DONE) { # 3.6.5. Reification of an Association my $ms = _parse ($_); #warn Dumper $ms; ok ($ms->tids ('lennon-mccartney'), '3.6.5. Reification of an Association'); is ($ms->toplets, $npt+5, ' additional'); is ($ms->asserts, $npa+2, ' additional'); my $a = $ms->reifies ('tm:lennon-mccartney'); is ($a->[TM->KIND], TM->ASSOC, ' reified assoc'); is (($ms->is_reified ($a))[0], 'tm:lennon-mccartney', ' reifying topic'); } } if (DONE) { # (anonymous) wildcard my $ms = _parse (q| ?xxx - "James Bond" . ?xxx = http://topic.one/ website: http://www.lennon.com/ . ?yyy = http://topic.two/ - "John Lennon" . ? = http://topic.three/ website: http://www.lennon3.com/ . ? = http://topic.four/ website: http://www.lennon4.com/ . ?yyy website: http://www.lennon2.com/ . ?xxx website: http://www.lennon1.com/ . |); #warn Dumper $ms; my $one = $ms->tids('http://topic.one/'); like ($one, qr/uuid-\d{10}/, 'named wildcard'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $one) ], [ 'James Bond', 'http://www.lennon.com/', 'http://www.lennon1.com/' ]), ' one chars'); my $two = $ms->tids('http://topic.two/'); like ($two, qr/uuid-\d{10}/, 'named wildcard'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $two) ], [ 'John Lennon', 'http://www.lennon2.com/' ]), ' two chars'); my $thr = $ms->tids('http://topic.three/'); like ($thr, qr/uuid-\d{10}/, 'named wildcard'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $thr) ], [ 'http://www.lennon3.com/' ]), ' thr chars'); my $fou = $ms->tids('http://topic.four/'); like ($fou, qr/uuid-\d{10}/, 'named wildcard'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $fou) ], [ 'http://www.lennon4.com/' ]), ' fou chars'); is ($ms->toplets, $npt+5, ' additional'); is ($ms->asserts, $npa+8, ' additional'); } if (DONE) { # (anonymous) wildcard my $ms = _parse (q| ?xxx = http://topic.one/ - "James Bond" . def TEMP ($l) ?yyy = http://topic.two/ website: $l . ?yyy website: http://www.lennon3.com/ . end ?xxx website: http://www.lennon1.com/ . TEMP ("http://www.lennon2.com/") ?yyy http://topic.three/ website: http://www.lennon4.com/ . def TEMP2 ($l) ?yyy = http://topic.four/ website: $l . ?yyy website: http://www.lennon5.com/ . end TEMP2 ("http://www.lennon4.com/") |); #warn Dumper $ms; my $one = $ms->tids('http://topic.one/'); like ($one, qr/uuid-\d{10}/, 'named wildcard in template'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $one) ], [ 'James Bond', 'http://www.lennon1.com/' ]), ' one chars'); my $two = $ms->tids('http://topic.two/'); like ($two, qr/uuid-\d{10}/, ' instantiated topic'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $two) ], [ 'http://www.lennon2.com/', 'http://www.lennon3.com/', # 'http://www.lennon4.com/' ]), ' two chars'); my $thr = $ms->tids( \ 'http://topic.three/'); isnt ($thr, $two, ' wildcarded different'); like ($thr, qr/uuid-\d{10}/, ' instantiated topic'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $thr) ], [ 'http://www.lennon4.com/', ]), ' thr chars'); my $fou = $ms->tids( 'http://topic.four/'); isnt ($fou, $two, ' wildcarded different'); isnt ($fou, $thr, ' wildcarded different'); like ($fou, qr/uuid-\d{10}/, ' instantiated topic'); ok (eq_set([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match_forall (char => 1, topic => $fou) ], [ 'http://www.lennon4.com/', 'http://www.lennon5.com/', ]), ' fou chars'); is ($ms->toplets, $npt+5, ' additional'); is ($ms->asserts, $npa+8, ' additional'); } if (DONE) { my $ms = _parse (q| xxx . %include inline:aaa . yyy . |); #warn Dumper $ms; ok ($ms->tids('xxx'), 'include: topics'); ok ($ms->tids('aaa'), 'include: topics'); ok ($ms->tids('yyy'), 'include: topics'); } __END__ 3.7.1. Singe line comment ------------------------- ::ctm # a single line with comments 3.7.2. Multiline comment ------------------------ ::ctm #( one comment line 2 )# map reify wildcard __END__ require_ok( 'TM::Materialized::LTM' ); { my $tm = new TM::Materialized::LTM (inline => ' '); ok ($tm->isa('TM::Materialized::Stream'), 'correct class'); ok ($tm->isa('TM::Materialized::LTM'), 'correct class'); } { # comments my $ms = _parse (q| [ aaa ] /* some comment [ bbb ] */ [ ccc ] |); #warn Dumper $ms; ok ($ms->tids ('aaa'), 'comment: outside'); ok (!$ms->tids ('bbb'), 'comment: inside'); ok ($ms->tids ('ccc'), 'comment: outside'); } die_ok (q{ /* [ aaa ] */ */ }, 'unparseable', 'invalid comment nesting'); { # encoding my $ms = _parse (q| @"utf-8" [ aaa ] |); ok (1, 'encoding: ignored'); } { # topic address my $ms = _parse (q| [aaa % "urn:aaa" ] |); # warn Dumper $ms; is ($ms->tids ('aaa'), $ms->tids ('urn:aaa'), 'reification: subject identifier ok'); } { # subject indicators my $ms = _parse (q| [aaa % "urn:aaa" @ "urn:xxx" @ "urn:yyy" ] |); # warn Dumper $ms; ok (eq_set ($ms->midlet ($ms->tids ('urn:aaa'))->[TM->INDICATORS], [ 'urn:xxx', 'urn:yyy' ]), 'indication: all found'); } { # topics types my $ms = _parse (q| [aaa: bbb ccc ] |); #warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:aaa'); ok (eq_set ([ map { $_->[TM->PLAYERS]->[0] } @res ], [ 'tm:bbb', 'tm:ccc' ]), 'topic: class values'); } { # topic basename my $ms = _parse (q| [aaa: bbb ccc = "AAA" ] |); #warn Dumper $ms; ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'name', iplayer => 'tm:aaa' ) ] , [ 'AAA' ]), 'topic: AAA basename'); } { # topic scoped basename my $ms = _parse (q| [aaa: bbb ccc = "AAAS" / sss ] |); #warn Dumper $ms; ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, scope => 'tm:sss', type => 'name', iplayer => 'tm:aaa' ) ] , [ 'AAAS' ]), 'topic: AAA basename (scoped)'); ok (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:sss' ) == 1, 'scope isa scope'); } { # topic, basename, sortname my $ms = _parse (q| [aaa: bbb ccc = "AAA" ; "SORTAAA" ] [xxx: yyy = "XXX"; "SORTXXX"; "DISPXXX" ] [uuu = "UUU"; "SORTUUU"; "DISPUUU" ] [vvv = "VVV"; "SORTVVV"; "DISPVVV" / sss ] |); #warn Dumper $ms; ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'name', iplayer => 'tm:aaa' ) ] , [ 'AAA' ]), 'topic: AAA basename'); # ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'name', iplayer => 'tm:aaa' ) ] , # [ 'SORTAAA' ]), 'topic: SORTAAA basename'); } { # topic external occurrence (typed) my $ms = _parse (q| {aaa, bbb, "http://xxxt/" } |); #warn Dumper $ms; ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'tm:bbb', iplayer => 'tm:aaa' ) ] , [ 'http://xxxt/' ]), 'topic: occurr typed'); ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'occurrence', iplayer => 'tm:aaa' ) ] , [ 'http://xxxt/' ]), 'topic: occurr (typed)'); } # untyped is not allowed in LTM? { # topic internal occurrence my $ms = _parse (q| {aaa, bbb, [[http://xxxt/]] } |); #warn Dumper $ms; ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'tm:bbb', iplayer => 'tm:aaa' ) ] , [ 'http://xxxt/' ]), 'topic: int occurr typed'); ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'occurrence', iplayer => 'tm:aaa' ) ] , [ 'http://xxxt/' ]), 'topic: int occurr (typed)'); } { # mix occurrences with topics my $ms = _parse (q| [ aaa : bbb ] { aaa, xxx, "http://xxx/" } { ccc, yyy, "http://yyy/" } [ ccc : ddd ] |); #warn Dumper $ms; ok (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:aaa' ) == 1, 'topic+occur: class'); ok (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:ccc' ) == 1, 'topic+occur: class'); ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'occurrence', iplayer => 'tm:aaa' ) ] , [ 'http://xxx/' ]), 'topic+occur: occurr'); ok (eq_set ([ map {$_->[0]} map { $_->[TM->PLAYERS]->[1] } $ms->match (TM->FORALL, type => 'occurrence', iplayer => 'tm:ccc' ) ] , [ 'http://yyy/' ]), 'topic+occur: occurr'); } #-- assocs -------------- { my $ms = _parse (q| aaa (play1: role1, play2: role2) bbb (play1: role1, play2: role2) ccc (play1, play2: role2) |); #warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => 'tm:aaa'); ok (eq_set ([ map { @{$_->[TM->PLAYERS]} } @res ], [ 'tm:play1', 'tm:play2' ]), 'assoc: players'); ok (eq_set ([ map { @{$_->[TM->ROLES]} } @res ], [ 'tm:role1', 'tm:role2' ]), 'assoc: roles'); @res = $ms->match (TM->FORALL, type => 'tm:bbb'); ok (scalar @res == 1, 'assoc: separate'); @res = $ms->match (TM->FORALL, type => 'tm:ccc'); ok (eq_set ([ map { @{$_->[TM->PLAYERS]} } @res ], [ 'tm:play1', 'tm:play2' ]), 'assoc: players'); ok (eq_set ([ map { @{$_->[TM->ROLES]} } @res ], [ 'thing', 'tm:role2' ]), 'assoc: roles (default)'); } { # scoped assoc my $ms = _parse (q| aaa (play1: role1, play2: role2) / sss aaa (play1: role1, play2: role2) aaa (play1: role1, play2: role2) / ttt |); ##warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => 'tm:aaa'); ok (scalar @res == 3, 'scoped mixed assoc: number'); ok (grep ($_->[TM->SCOPE] eq 'tm:ttt', @res), 'scoped mixed assoc: scoping'); ok (grep ($_->[TM->SCOPE] eq 'tm:sss', @res), 'scoped mixed assoc: scoping'); ok (grep ($_->[TM->SCOPE] eq 'us', @res), 'scoped mixed assoc: scoping'); foreach my $r (@res) { ok (eq_set ([ @{$r->[TM->PLAYERS]} ], [ 'tm:play1', 'tm:play2' ]), 'scoped mixed assoc: players'); ok (eq_set ([ @{$r->[TM->ROLES]} ], [ 'tm:role1', 'tm:role2' ]), 'scoped mixed assoc: roles'); } } { # assoc with nested topic my $ms = _parse (q| aaa ( [ play1: ccc ]: role1, play2: role2) |); #warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => 'tm:aaa'); ok (eq_set ([ map { @{$_->[TM->PLAYERS]} } @res ], [ 'tm:play1', 'tm:play2' ]), 'assoc + embed: players'); ok (eq_set ([ map { @{$_->[TM->ROLES]} } @res ], [ 'tm:role1', 'tm:role2' ]), 'assoc + embed: roles'); @res = $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:play1'); ok (eq_set ([ map { @{$_->[TM->PLAYERS]} } @res ], [ 'tm:play1', 'tm:ccc' ]), 'assoc + embed: types'); } # reifications { # reified assocs my $ms = _parse (q| aaa ( play1: role1, play2: role2) ~ xxx |); #warn Dumper $ms; my ($a) = $ms->match (TM->FORALL, type => 'tm:aaa'); is ($a->[TM->LID], $ms->midlet ('tm:xxx')->[TM->ADDRESS], 'assoc reification'); } { # reified occurrence my $ms = _parse (q| {aaa, bbb, "http://xxxt/" } ~ xxx |); #warn Dumper $ms; my ($a) = $ms->match (TM->FORALL, type => 'tm:bbb'); is ($a->[TM->LID], $ms->midlet ('tm:xxx')->[TM->ADDRESS], 'occurrence reification'); } { # reified basename my $ms = _parse (q| [ aaa = "AAA" ~ xxx ] |); #warn Dumper $ms; my ($a) = $ms->match (TM->FORALL, type => 'name'); is ($a->[TM->LID], $ms->midlet ('tm:xxx')->[TM->ADDRESS], 'basename reification'); } #== Directives ======================== { # wrong VERSION format die_ok (q| #VERSION "123" |, 'not supported'); } { # wrong VERSION die_ok (q| #VERSION "1.4" |, 'not supported'); } { # VERSION my $ms = _parse (q| #VERSION "1.3" [ aaa ] |); ok (1, 'version supported'); } { # TOPICMAP die_ok (q| #TOPICMAP ~ xxxx |, 'use proper'); } { # INCLUDE die_ok (q| [aaa] #INCLUDE "xyz:abc" |, 'unable to load'); } { # INCLUDE my $ms = _parse (q| [ aaa ] #INCLUDE "inline: [ bbb ]" [ ccc ] |); # warn Dumper $ms; ok ($ms->midlet ('tm:aaa'), 'include: topic'); ok ($ms->midlet ('tm:bbb'), 'include: topic'); ok ($ms->midlet ('tm:ccc'), 'include: topic'); } { die_ok (q| aa:uuu (bbb:play: bbb:role) |, 'unparseable'); } { # PREFIXES my $ms = _parse (q| #PREFIX aaa @ "http://xxxx/#" #PREFIX bbb @ "http://yyyy/#" aaa:uuu (play: bbb:role) |); # warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => $ms->tids ('http://xxxx/#uuu')); ok (scalar @res == 1, 'prefixed assoc name: found'); ok (eq_set ([ map { @{$_->[TM->PLAYERS]} } @res ], [ 'tm:play' ]), 'unprefixed player name'); my $id = $ms->tids ('http://yyyy/#role'); ok (eq_set ([ map { @{$_->[TM->ROLES]} } @res ], [ $id ]), 'prefixed role name'); } die_ok (q{ #MERGEMAP "inline: [ bbb ]" "rumsti" }, 'unsupported', 'invalid TM format'); { # MERGEMAP my $ms = _parse (q| #MERGEMAP "inline: [ bbb ]" "ltm" [ aaa ] [ ccc ] |); # warn Dumper $ms; TODO: { local $TODO = "merging"; ok ($ms->tids ('aaa'), 'merge: topic'); ok ($ms->tids ('bbb'), 'merge: topic'); ok ($ms->tids ('ccc'), 'merge: topic'); } } { # MERGEMAP (default my $ms = _parse (q| #MERGEMAP "inline: [ bbb ]" [ aaa ] [ ccc ] |); # warn Dumper $ms; TODO: { local $TODO = "merging (default)"; ok ($ms->tids ('aaa'), 'merge: topic'); ok ($ms->tids ('bbb'), 'merge: topic'); ok ($ms->tids ('ccc'), 'merge: topic'); } } __END__ __END__ die_ok (q{ format-for ([ ltm ] : standard, topic-maps ) @"abssfsdf" }, 1, 'invalid encoding'); $tm = new XTM (tie => new XTM::LTM ( text => q{ @"iso8859-1" { ltm , test , [[Ich chan Glaas ässe, das tuet mir nöd weeh]] } })); like ($tm->topic ('ltm')->occurrences->[0]->resource->data, qr/\x{E4}sse/, 'encoding from iso8859-1'); die_ok (q{ format-for ([ ltm ] : standard, topic-maps ) xxxx { ltm , test , "http://rumsti/" } }, 1, 'unknown keyword'); die_ok (q{ format-for ([ ltm ] : standard, topic-maps }, 1, 'missing terminator 1'); die_ok (q{ [ ltm : format <= "The linear topic map notation" @ "http://something1/" @ "http://something2/" ] }, 1, 'invalid terminator 1'); die_ok (' { ltm , test , "http://rumsti/" ' , 1, 'missing terminator 2'); die_ok (' { ltm , test , "http://rumsti/" } abc' , 1, 'additional nonparsable text'); $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm ] { ltm , test , [[http://rumsti/ ramsti romsti ]] } })); is (@{$tm->topics('occurrence regexps /rumsti/')}, 1, 'occurrence with topic'); is (@{$tm->topics('occurrence regexps /romsti/')}, 1, 'occurrence with topic, multiline'); #print Dumper $tm; $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm ] { ltm , test , "http://rumsti/" } })); is (@{$tm->topics('occurrence regexps /rumsti/')}, 1, 'occurrence with topic'); is (@{$tm->topics()}, 2, 'occurrence with topic, 2'); #print Dumper $tm; $tm = new XTM (tie => new XTM::LTM ( text => q{ { ltm , test , "http://rumsti/" } { ltm , test2 , "http://ramsti/" } { ltm2, test , "http://rumsti/" } })); is (@{$tm->topics('occurrence regexps /rumsti/')}, 2, 'occurrence wo topic'); $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm : format = "The linear topic map notation" @ "http://something1/" @ "http://something2/" ] })); is (@{$tm->topics('indicates regexps /something1/')}, 1, 'subject indication1'); is (@{$tm->topics('indicates regexps /something2/')}, 1, 'subject indication2'); $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm : format = "The linear topic map notation" % "http://something/" ] })); is (@{$tm->topics('reifies regexps /something/')}, 1, 'subject reification'); #__END__ $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm : format = "The linear topic map notation" ] })); is (@{$tm->topics('baseName regexps /linear/')}, 1, 'basename wo scope'); $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm : format = "The linear topic map notation / scope1" ] })); is (@{$tm->topics('baseName regexps /linear/')}, 1, 'basename with scope'); #__END__ # with types my @types = qw(format1 format2 format3); $tm = new XTM (tie => new XTM::LTM ( text => q{ [ ltm : }.join (" ", @types).q{ ] })); is (@{$tm->topics()}, 4, 'topic with types'); foreach my $t (@types) { is (@{$tm->topics("is-a $t")}, 1, "finding $t"); } __END__ use strict; # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More qw(no_plan); use Data::Dumper; $Data::Dumper::Indent = 1; sub _chomp { my $s = shift; chomp $s; return $s; } use TM; use TM::PSI; ok (1); __END__ sub _parse { my $text = shift; my $ms = new TM (baseuri => 'tm:'); my $p = new TM::AsTMa::Fact (store => $ms); my $i = $p->parse ("$text\n"); return $ms; } sub _q_players { my $ms = shift; # my @res = $ms->match (TM->FORALL, @_); # warn "res no filter ".Dumper \@res; my @res = grep ($_ !~ m|^tm:|, map { ref($_) ? $_->[0] : $_ } map { @{$_->[TM->PLAYERS]} } $ms->match (TM->FORALL, @_)); # warn "res ".Dumper \@res; return \@res; } ##=================================================================================== #== TESTS =========================================================================== require_ok( 'TM::AsTMa::Fact' ); { # class ok my $p = new TM::AsTMa::Fact; ok (ref($p) eq 'TM::AsTMa::Fact', 'class ok'); } { #-- structural my $ms = _parse ('aaa (bbb) ccc (bbb) '); #warn Dumper $ms; exit; is (scalar $ms->match_forall (type => 'isa', irole => 'class', iplayer => 'tm:bbb'), 2, 'two types for bbb'); ok (eq_array ([ $ms->mids ('aaa', 'bbb', 'ccc') ], [ 'tm:aaa', 'tm:bbb', 'tm:ccc' ]), 'aaa, bbb, ccc internalized'); } { #-- structural my $ms = _parse ('aaa (bbb) '); #warn Dumper $ms; is (scalar $ms->match (TM->FORALL, type => 'isa', arole => 'instance', aplayer => 'tm:aaa', brole => 'class', bplayer => 'tm:bbb'), 1, 'one type for aaa'); ok (eq_array ([ $ms->mids ('aaa', 'bbb') ], [ 'tm:aaa', 'tm:bbb' ]), 'aaa, bbb internalized'); } { my $ms = _parse ('aaa '); #warn Dumper $ms; is ($ms->mids ('aaa'), 'tm:aaa', 'aaa implicitely internalized'); } { # structural topic my $ms = _parse (q| aaa is-a bbb bn: AAA oc: http://BBB in: blabla bla |); #warn Dumper $ms; is (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:aaa' ), 1, 'one type for aaa'); is (scalar $ms->match (TM->FORALL, irole => 'thing', iplayer => 'tm:aaa' ), 4, 'chars for aaa'); is (scalar $ms->match (TM->FORALL, type => 'name', irole => 'thing', iplayer => 'tm:aaa' ), 1, 'basenames for aaa'); is (scalar $ms->match (TM->FORALL, type => 'occurrence', irole => 'thing', iplayer => 'tm:aaa' ), 2, 'occurrences for aaa 1'); } #-- syntactic issues ---------------------------------------------------------------- my $npa = scalar keys %{$TM::infrastructure->{assertions}}; my $npt = scalar keys %{$TM::infrastructure->{mid2iid}}; { my $ms = _parse (q| # this is AsTMa |); #warn Dumper $ms; is (scalar $ms->match(), $npa, 'empty map 1 (assertions)'); is ($ms->toplets, $npt, 'empty map 2 (toplets)'); } { # empty line with blanks my $ms = _parse (q| topic1 topic2 |); ##warn Dumper $ms; is (scalar $ms->toplets(), $npt+2, 'empty line contains blanks'); } { # empty lines with \r my $ms = _parse (q| topic1 topic2 topic3 |); is (scalar $ms->toplets(), $npt+3, 'empty line \r contains blanks'); } { # using TABs as separators my $ms = _parse (q| topic1 ( topic2 ) # comment |); #warn Dumper $ms; is (scalar $ms->toplets, $npt+2, 'using TABs as separators'); } { my $ms = _parse (q| # comment1 aaa (bbbbb cccc dddd) #comment2 #comment4 ccc (bbb) #comment3 #comment4 ddd (xxxx) #comment5 |); ##warn Dumper $ms; is (scalar $ms->toplets, $npt+8, 'test comment/separation'); is (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:aaa' ), 3, 'types for aaa'); is (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:ccc' ), 1, 'type for ccc'); is (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:ddd' ), 1, 'type for ddd'); } { # line continuation with comments my $ms = _parse (q| topic1 # comment \ topic2 |); is (scalar $ms->toplets, $npt+1, 'continuation in comment'); } { # line continuation with comments my $ms = _parse (q| topic1 # comment \ topic2 |); is (scalar $ms->toplets, $npt+2, 'continuation in comment, not 1'); } { # line continuation with comments my $ms = _parse (q| topic1 # comment \ topic2 |); is (scalar $ms->toplets, $npt+2, 'continuation in comment, not 2'); } { # line continuation my $ms = _parse (q| aaa (bbbbb \ cccc \ dddd) | ); is (scalar $ms->toplets, $npt+4, 'line continuation'); is (scalar $ms->match (TM->FORALL, type => 'isa', irole => 'instance', iplayer => 'tm:aaa' ), 3, 'types for aaa'); } { # line continuation, not my $ms = _parse (q| aaa bn: AAA in: a \ within the text is ok in: also one with a \\ followed by a blank: \\ in: this is a new one \\ in: this is not a new one |); ##warn Dumper $ms; my @res = $ms->match (TM->FORALL, type => 'occurrence', irole => 'thing', iplayer => 'tm:aaa' ); is (scalar @res, 3, 'ins for aaa'); ##warn Dumper \@res; ##warn Dumper [ map { ${$_->[TM->PLAYERS]->[1]}} @res ]; ok (eq_set ([ map { $_->[0] } map { $_->[TM->PLAYERS]->[1] } @res ], [ 'a \ within the text is ok', 'also one with a \ followed by a blank: \\', # blank is gone now 'this is a new one in: this is not a new one']), 'same text'); } { # line continuation, not \\ my $ms = _parse (q| aaa (bbbb \ ) # this is a continuation bn: but not this \\\\ in: should be separate | ); ##warn Dumper $ms; is (scalar $ms->match, $npa+3, 'line continuation, =3'); } { # string detection my $ms = _parse (q| aaa in: AAA bbb in: <<< xxxxxxxxxxxxx yyyyyyyyyy zzzzzz <<< ccc in: <