rtm 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/activetopicmaps.rb +55 -6
- data/lib/rtm.rb +27 -8
- data/lib/rtm/backend/active_record.rb +29 -24
- data/lib/rtm/backend/active_record/association_and_role.rb +3 -24
- data/lib/rtm/backend/active_record/locators.rb +2 -0
- data/lib/rtm/backend/active_record/name_variant_occurrence.rb +5 -4
- data/lib/rtm/backend/active_record/tm_delegator.rb +0 -75
- data/lib/rtm/backend/active_record/tmdm.rb +5 -0
- data/lib/rtm/backend/active_record/topic.rb +10 -76
- data/lib/rtm/backend/active_record/topic_map.rb +30 -1
- data/lib/rtm/backend/active_record/traverse_associations.rb +86 -0
- data/lib/rtm/io/from_xtm2_libxml.rb +1 -1
- data/lib/rtm/locator_helpers.rb +16 -0
- data/lib/rtm/sugar/role/counterparts.rb +51 -0
- data/lib/rtm/sugar/topic/characteristics.rb +15 -0
- data/lib/rtm/sugar/topic/counterparts.rb +15 -0
- data/lib/rtm/sugar/topic/hash_access.rb +55 -0
- data/lib/rtm/sugar/topic/identifier_direct.rb +11 -0
- data/lib/rtm/sugar/topic/predefined_associations.rb +42 -0
- data/test/base_test.rb +153 -0
- metadata +84 -67
- data/lib/rtm/io/from_xtm2_jaxp.rb +0 -89
@@ -54,6 +54,8 @@ module RTM::AR
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.create(base_locator, params={})
|
57
|
+
bl_uri = URI.parse(base_locator)
|
58
|
+
raise "The locator for the Topic Map must be absolute! \"#{base_locator}\" is not an absolute locator." unless bl_uri.absolute?
|
57
59
|
tm = self.wrap(TMDM::TopicMap.find_or_create_by_base_locator(base_locator))
|
58
60
|
yield tm if block_given?
|
59
61
|
tm
|
@@ -119,6 +121,7 @@ module RTM::AR
|
|
119
121
|
|
120
122
|
# internal helper for by_item_identifier, doesn't wrap result
|
121
123
|
def _by_item_identifier(iid)
|
124
|
+
iid = RTM::LocatorHelpers.iid2iri(iid) if RTM::LocatorHelpers.is_a_iid?(iid)
|
122
125
|
ii = __getobj__.locators.find_by_reference(resolve(iid)) #, :include => [ :topic_map_construct ])
|
123
126
|
return ii.topic_map_construct if ii
|
124
127
|
nil
|
@@ -132,6 +135,7 @@ module RTM::AR
|
|
132
135
|
|
133
136
|
# internal helper for topic_by_item_identifier!, doesn't wrap result
|
134
137
|
def _topic_by_item_identifier!(iid)
|
138
|
+
iid = RTM::LocatorHelpers.iid2iri(iid) if RTM::LocatorHelpers.is_a_iid?(iid)
|
135
139
|
ii = __getobj__.locators.find_or_create_by_reference(resolve(iid))#, :include => [ :topic_map_construct ])
|
136
140
|
return ii.topic_map_construct if ii.topic_map_construct && ii.topic_map_construct_type =~ /::Topic$/
|
137
141
|
top2 = _topic_by_subject_identifier(resolve(iid))
|
@@ -187,6 +191,8 @@ module RTM::AR
|
|
187
191
|
raise "Locator may not be nil" unless iri
|
188
192
|
if RTM::LocatorHelpers.is_a_slo?(iri)
|
189
193
|
_topic_by_subject_locator(iri)
|
194
|
+
elsif RTM::LocatorHelpers.is_a_iid?(iri)
|
195
|
+
_topic_by_item_identifier(iri)
|
190
196
|
elsif URI.parse(iri).absolute?
|
191
197
|
_topic_by_subject_identifier(iri)
|
192
198
|
else
|
@@ -198,13 +204,22 @@ module RTM::AR
|
|
198
204
|
raise "Locator may not be nil" unless iri
|
199
205
|
if RTM::LocatorHelpers.is_a_slo?(iri)
|
200
206
|
_topic_by_subject_locator!(iri)
|
207
|
+
elsif RTM::LocatorHelpers.is_a_iid?(iri)
|
208
|
+
_topic_by_item_identifier!(iri)
|
201
209
|
elsif URI.parse(iri).absolute?
|
202
210
|
_topic_by_subject_identifier!(iri)
|
203
211
|
else
|
204
212
|
_topic_by_item_identifier!(iri)
|
205
213
|
end
|
206
214
|
end
|
207
|
-
|
215
|
+
|
216
|
+
%w[topic association role name occurrence variant].each do |x|
|
217
|
+
eval <<-EOI
|
218
|
+
def _#{x}_by_id(id)
|
219
|
+
__getobj__.#{x}s.find(id)
|
220
|
+
end
|
221
|
+
EOI
|
222
|
+
end
|
208
223
|
public
|
209
224
|
# returns an item identifier from the topic_map if it exists
|
210
225
|
def item_identifier(iid)
|
@@ -248,8 +263,11 @@ module RTM::AR
|
|
248
263
|
#
|
249
264
|
# Returns nil if the Topic does not exist.
|
250
265
|
#
|
266
|
+
# It's also possible to pass a number, which is used to fetch a topic using the internal id. In this case, an exception is thrown, if the topic does not exist.
|
267
|
+
#
|
251
268
|
def topic_by_locator(iri)
|
252
269
|
return iri if iri.is_a? Topic
|
270
|
+
return topic_by_id(iri) if iri.is_a? Integer
|
253
271
|
# @tblc ||= {}
|
254
272
|
# t = @tblc[iri]
|
255
273
|
# return t if t
|
@@ -263,9 +281,11 @@ module RTM::AR
|
|
263
281
|
# its (absolute) subject identifier or its (absolute and by "=" prepended) subject locator)
|
264
282
|
#
|
265
283
|
# If there is no topic with this item identifier, subject identifier or subject locator, it is created.
|
284
|
+
# Please be aware, the creation does not work with the internal (numeric) ids.
|
266
285
|
#
|
267
286
|
def topic_by_locator!(iri)
|
268
287
|
return iri if iri.is_a? Topic
|
288
|
+
return topic_by_id(iri) if iri.is_a? Integer
|
269
289
|
# @tblc ||= {}
|
270
290
|
# t = @tblc[iri]
|
271
291
|
# return t if t
|
@@ -275,6 +295,15 @@ module RTM::AR
|
|
275
295
|
end
|
276
296
|
alias :get! :topic_by_locator!
|
277
297
|
|
298
|
+
%w[topic association role name occurrence variant].each do |x|
|
299
|
+
eval <<-EOI
|
300
|
+
def #{x}_by_id(id)
|
301
|
+
#{x.camelize}.wrap(_#{x}_by_id(id))
|
302
|
+
end
|
303
|
+
alias :#{x[0].chr}id :#{x}_by_id
|
304
|
+
EOI
|
305
|
+
end
|
306
|
+
|
278
307
|
# I am not sure if this is at all correct. TMDM doesn't say a word about it
|
279
308
|
# and the approach to compare topic maps is CXTM. I chose this because we
|
280
309
|
# should (at least at the time of writing) have only one topic with a given
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module RTM::AR
|
2
|
+
module TraverseAssociations
|
3
|
+
def define_association(prop, options={})
|
4
|
+
r = options[:rule]
|
5
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION__)", 1)
|
6
|
+
def direct_#{prop}_roles
|
7
|
+
# prefetch typing topics
|
8
|
+
rtype = @ips_#{prop}_rtype ||= self.topic_map.get("#{r[:role_type]}")
|
9
|
+
atype = @ips_#{prop}_atype ||= self.topic_map.get("#{r[:association_type]}")
|
10
|
+
otype = @ips_#{prop}_otype ||= self.topic_map.get("#{r[:other_role_type]}")
|
11
|
+
# return nothing if any of the typing topics does not exist
|
12
|
+
return [] unless rtype && atype && otype
|
13
|
+
# we do that only here and not earlier because some might me nil
|
14
|
+
rtype = rtype.id
|
15
|
+
atype = atype.id
|
16
|
+
otype = otype.id
|
17
|
+
self.__getobj__.roles.map{|r|
|
18
|
+
r.ttype_id != nil &&
|
19
|
+
r.ttype_id == rtype &&
|
20
|
+
r.parent.roles.size == #{r[:association_arity]} &&
|
21
|
+
r.parent != nil &&
|
22
|
+
r.parent.ttype_id == atype &&
|
23
|
+
(r2 = r.parent.roles.select{|r2| r2.ttype_id != nil &&
|
24
|
+
r2.ttype_id == otype}.first) &&
|
25
|
+
r2}.select{|r2| r2}.map{|r2| AssociationRole.wrap(r2)}
|
26
|
+
end
|
27
|
+
def direct_#{prop}
|
28
|
+
direct_#{prop}_roles.map{|r2| r2.player}.uniq
|
29
|
+
end
|
30
|
+
EOS
|
31
|
+
|
32
|
+
if r[:transitive]
|
33
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION2__)", 1)
|
34
|
+
def #{prop}
|
35
|
+
d = todo = self.direct_#{prop}
|
36
|
+
while todo.size > 0
|
37
|
+
todo = todo.map{|dt| dt.direct_#{prop}}.flatten.uniq - d
|
38
|
+
d += todo
|
39
|
+
end
|
40
|
+
d
|
41
|
+
#d2 = self.direct_#{prop}.map {|dt| dt.#{prop}}.flatten
|
42
|
+
#(d+d2).uniq
|
43
|
+
end
|
44
|
+
EOS
|
45
|
+
else
|
46
|
+
if r[:infer] && r[:infer_other] # this part is not testet at all!
|
47
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION3a__)", 1)
|
48
|
+
def #{prop}
|
49
|
+
dps = (self + self.#{r[:infer]}).flatten.uniq
|
50
|
+
dcps = dps.map{|d2| d2.direct_#{prop}}
|
51
|
+
(dcps + dcps.map{|d2| d2.#{r[:infer_other]}}).flatten.uniq
|
52
|
+
end
|
53
|
+
EOS
|
54
|
+
elsif r[:infer]
|
55
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION3__)", 1)
|
56
|
+
def #{prop}
|
57
|
+
(self.direct_#{prop} + self.#{r[:infer]}.map{|d2| d2.direct_#{prop}}).flatten.uniq
|
58
|
+
end
|
59
|
+
EOS
|
60
|
+
elsif r[:infer_other]
|
61
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION4__)", 1)
|
62
|
+
def #{prop}
|
63
|
+
d = self.direct_#{prop}
|
64
|
+
(d + d.map{|d2| d2.#{r[:infer_other]}}).flatten.uniq
|
65
|
+
end
|
66
|
+
EOS
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if r[:add]
|
70
|
+
module_eval(<<-EOS, "(__AR_DELEGATOR_DEFINE_ASSOCIATION_ADD_REMOVE__)", 1)
|
71
|
+
def add_#{r[:add]}(t)
|
72
|
+
a = self.topic_map.create_association("#{r[:association_type]}")
|
73
|
+
a.create_role self, "#{r[:role_type]}"
|
74
|
+
a.create_role t, "#{r[:other_role_type]}"
|
75
|
+
a
|
76
|
+
# TODO add_x in define_association needs to trigger reload of the topics somewhere
|
77
|
+
end
|
78
|
+
def remove_#{r[:add]}(t)
|
79
|
+
direct_#{prop}_roles.select{|r| r.player == t}.each{|r| r.parent.remove}
|
80
|
+
# TODO remove_x in define_association needs to trigger reload of the topics somewhere
|
81
|
+
end
|
82
|
+
EOS
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -33,7 +33,7 @@ module XML
|
|
33
33
|
# Acts as Callback structure for the LibXML-Ruby SAX Parser and calls
|
34
34
|
# a REXML SAX2Listener API.
|
35
35
|
class LibXMLSax2wrapper
|
36
|
-
include XML::SaxParser::Callbacks
|
36
|
+
include LibXML::XML::SaxParser::Callbacks
|
37
37
|
def initialize(rexml_sax2listener)
|
38
38
|
@dest = rexml_sax2listener
|
39
39
|
@ns = Hash.new("http://www.topicmaps.org/xtm/")
|
data/lib/rtm/locator_helpers.rb
CHANGED
@@ -19,5 +19,21 @@ module RTM
|
|
19
19
|
def self.is_a_slo?(iri)
|
20
20
|
iri.to_s[0] == "="[0]
|
21
21
|
end
|
22
|
+
|
23
|
+
def self.iid2iri(slo)
|
24
|
+
slo = slo.to_s
|
25
|
+
slo = slo[1..-1].lstrip if slo[0] == "^"[0] # remove = if slo starts with it
|
26
|
+
slo
|
27
|
+
end
|
28
|
+
def self.iri2iid(iri)
|
29
|
+
return "^#{iri}" if slo[0] == "="[0]
|
30
|
+
iri
|
31
|
+
end
|
32
|
+
|
33
|
+
# returns true if the String or Locator given starts with "^".
|
34
|
+
# This catches only the prefixing-style, not the local-identifier (non-absolute-iri) style
|
35
|
+
def self.is_a_iid?(iri)
|
36
|
+
iri.to_s[0] == "^"[0]
|
37
|
+
end
|
22
38
|
end
|
23
39
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RTM::Sugar
|
2
|
+
module Role
|
3
|
+
module Counterparts
|
4
|
+
# This method fetches all roles from the parent association of this role, except itself (i.e. current role).
|
5
|
+
# A filter-hash may be used to filter for the type of the other role (:otype =>topic_reference).
|
6
|
+
# Examples:
|
7
|
+
# this_role.counterparts # returns all
|
8
|
+
# this_role.counterparts(:otype => some_topic) # returns only other roles which have type some_topic
|
9
|
+
# this_role.counterparts(:otype => "some_reference") # as above, looking up the reference first
|
10
|
+
def counterparts(filter={})
|
11
|
+
self.parent.roles.reject{|r| r.id==self.id}.
|
12
|
+
select{|r| filter[:otype] ? r.type == self.topic_map.get(filter[:otype]) : true}
|
13
|
+
end
|
14
|
+
|
15
|
+
# This methods fetches all players of the parent association of this role, except the player of itself.
|
16
|
+
# It accepts a filter-hash like the counterparts-method.
|
17
|
+
def counterplayers(*args)
|
18
|
+
self.counterparts(*args).map{|r| r.player}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Fetches the other role, if the parent association is binary.
|
22
|
+
def counterpart
|
23
|
+
n = self.parent.roles.size
|
24
|
+
raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2
|
25
|
+
return nil if n == 1
|
26
|
+
self.counterparts.first
|
27
|
+
end
|
28
|
+
|
29
|
+
# Fetches the player of the other role, if the parent association is binary.
|
30
|
+
def counterplayer
|
31
|
+
n = self.parent.roles.size
|
32
|
+
raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations." if n > 2
|
33
|
+
return nil if n == 1
|
34
|
+
self.counterparts.first.player
|
35
|
+
end
|
36
|
+
|
37
|
+
# Fetches all roles of the (binary) parent associations which play the same role in the same with the counterplayer
|
38
|
+
# TODO: filter not only otype but also atype and rtype.
|
39
|
+
def peers
|
40
|
+
cp = self.counterpart
|
41
|
+
cp.player.roles.select{|r| r.type == cp.type}.map{|r| r.counterpart}
|
42
|
+
end
|
43
|
+
# Fetches all players of roles being in the same association with another topic as self
|
44
|
+
# Example: current_role is a role of player "me" and type "employee"
|
45
|
+
# current_role.peerplayers # returns all employees of my company (including me)
|
46
|
+
def peerplayers
|
47
|
+
self.peers.map{|r| r.player}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RTM::Sugar
|
2
|
+
module Topic
|
3
|
+
module Characteristics
|
4
|
+
def characteristics
|
5
|
+
topic_names.to_a + occurrences.to_a
|
6
|
+
end
|
7
|
+
def internal_occurrences
|
8
|
+
occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
|
9
|
+
end
|
10
|
+
def external_occurrences
|
11
|
+
occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RTM::Sugar
|
2
|
+
module Topic
|
3
|
+
module Counterparts
|
4
|
+
def counterparts(filter={})
|
5
|
+
self.roles.
|
6
|
+
select{|r| filter[:rtype] ? r.type == self.topic_map.get(filter[:rtype]) : true}.
|
7
|
+
select{|r| filter[:atype] ? r.parent.type == self.topic_map.get(filter[:atype]) : true}.
|
8
|
+
inject([]){|all,r| all+=r.counterparts(filter)}
|
9
|
+
end
|
10
|
+
def counterplayers(*args)
|
11
|
+
return self.counterparts(*args).map{|r| r.player}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RTM::Sugar
|
2
|
+
module Topic
|
3
|
+
module HashAccess
|
4
|
+
def [](cref)
|
5
|
+
raise "Characteristic reference must be a String" unless cref.is_a? String
|
6
|
+
is_name, type_reference, scope_reference = resolve_characteristic(cref)
|
7
|
+
if is_name
|
8
|
+
type_reference = RTM::PSI[:name_type] if type_reference == :any
|
9
|
+
names.select{|n| n.type == topic_map.get(type_reference)}
|
10
|
+
else
|
11
|
+
raise "No occurrence type given" if type_reference == :any
|
12
|
+
occurrences.select{|o| o.type == topic_map.get(type_reference)}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(cref, value)
|
17
|
+
is_name, type_reference, scope_reference = resolve_characteristic(cref)
|
18
|
+
if is_name
|
19
|
+
nametype = type_reference || topic_map.get!(RTM::PSI[:name_type])
|
20
|
+
n = create_name(value, nametype)
|
21
|
+
n
|
22
|
+
else
|
23
|
+
raise "No occurrence type given" if type_reference == :any
|
24
|
+
o = create_occurrence(value, type_reference)
|
25
|
+
o
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def resolve_characteristic(ref)
|
31
|
+
ref =~ /^(-\s*)?(.+)?$/
|
32
|
+
is_name = $1 ? true : false
|
33
|
+
type, scope = resolve_type_and_scope($2)
|
34
|
+
[is_name, type, scope]
|
35
|
+
end
|
36
|
+
|
37
|
+
def resolve_type_and_scope(ref)
|
38
|
+
return [ref, :ucs] if ref.is_a? Topic
|
39
|
+
type, scope = ref.split('@', -1)
|
40
|
+
if type.blank?
|
41
|
+
type = :any
|
42
|
+
else
|
43
|
+
type.strip!
|
44
|
+
end
|
45
|
+
if scope
|
46
|
+
scope = scope.strip.split(/\s+/)
|
47
|
+
scope = :ucs if scope.blank?
|
48
|
+
else
|
49
|
+
scope = :any
|
50
|
+
end
|
51
|
+
[type, scope]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RTM::Sugar
|
2
|
+
module Topic
|
3
|
+
module PredefinedAssociations
|
4
|
+
extend RTM::AR::TraverseAssociations
|
5
|
+
# maybe these pairs could be declared each with a single statement and a reversible option
|
6
|
+
define_association :types, :type => :Topic, :rule => {
|
7
|
+
:transitive => false,
|
8
|
+
:role_type => RTM::PSI[:instance],
|
9
|
+
:association_type => RTM::PSI[:type_instance],
|
10
|
+
:association_arity => 2,
|
11
|
+
:other_role_type => RTM::PSI[:type],
|
12
|
+
:infer_other => :supertypes,
|
13
|
+
:add => :type,
|
14
|
+
}
|
15
|
+
define_association :instances, :type => :Topic, :rule => {
|
16
|
+
:transitive => false,
|
17
|
+
:role_type => RTM::PSI[:type],
|
18
|
+
:association_type => RTM::PSI[:type_instance],
|
19
|
+
:association_arity => 2,
|
20
|
+
:other_role_type => RTM::PSI[:instance],
|
21
|
+
:infer => :subtypes,
|
22
|
+
:add => :instance,
|
23
|
+
}
|
24
|
+
define_association :supertypes, :type => :Topic, :rule => {
|
25
|
+
:transitive => true,
|
26
|
+
:role_type => RTM::PSI[:subtype],
|
27
|
+
:association_type => RTM::PSI[:supertype_subtype],
|
28
|
+
:association_arity => 2,
|
29
|
+
:other_role_type => RTM::PSI[:supertype],
|
30
|
+
:add => :supertype,
|
31
|
+
}
|
32
|
+
define_association :subtypes, :type => :Topic, :rule => {
|
33
|
+
:transitive => true,
|
34
|
+
:role_type => RTM::PSI[:supertype],
|
35
|
+
:association_type => RTM::PSI[:supertype_subtype],
|
36
|
+
:association_arity => 2,
|
37
|
+
:other_role_type => RTM::PSI[:subtype],
|
38
|
+
:add => :subtype,
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/test/base_test.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
#
|
2
|
+
# Some basic tests... feel free to add more :)
|
3
|
+
#
|
4
|
+
|
5
|
+
|
6
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'rtm'
|
10
|
+
|
11
|
+
class BaseTest < Test::Unit::TestCase
|
12
|
+
# There are a bunch of global assertions in here so it cannot be parallelized
|
13
|
+
# with other tests, that's why it is all in one. What can we do about that?
|
14
|
+
def test_connect
|
15
|
+
assert RTM.connect, "Connection to memory backend failed"
|
16
|
+
assert_equal 0, RTM[].size, "There should be no topic maps in a newly created environment."
|
17
|
+
base_locator = "http://rtm.rubyforge.org/tests/base_test"
|
18
|
+
m = RTM.create base_locator
|
19
|
+
assert_equal 1, RTM[].size, "After creation of a topic map, there should be one."
|
20
|
+
assert_kind_of RTM::TopicMap, m, "RTM.create should create something which includes RTM::TopicMap"
|
21
|
+
assert_equal base_locator, m.base_locator, "The base_locator should be initialized properly."
|
22
|
+
assert m.respond_to?(:topics), "The topic map should respond to :topics"
|
23
|
+
assert m.respond_to?(:associations), "The topic map should respond to :topics"
|
24
|
+
assert_equal 0, m.topics.size, "A new topic map should have no topics."
|
25
|
+
assert_equal 0, m.associations.size, "A new topic map should have no associations."
|
26
|
+
assert m.reifier.nil?, "A new topic map should not be reified yet."
|
27
|
+
assert_equal 0, m.item_identifiers.size, "A new topic map should "
|
28
|
+
|
29
|
+
# assigning a reifier
|
30
|
+
m.reifier = "a_topic_which_reifies_the_topic_map"
|
31
|
+
assert_equal 1, m.topics.size, "A topic should have been created to reify the topic map."
|
32
|
+
assert_kind_of RTM::Topic, m.reifier, "A reifier should be a Topic."
|
33
|
+
|
34
|
+
assert_equal m, m.topics.first.reified, "The only topic out there should reify the map (not generally, but here)."
|
35
|
+
assert_equal m.base_locator, m.topics.first.reified.base_locator, "The only topic out there should reify the map. Check base locator."
|
36
|
+
assert_equal m.__getobj__, m.topics.first.reified.__getobj__, "The only topic out there should reify the map. Look inside."
|
37
|
+
|
38
|
+
t = m.create_topic
|
39
|
+
assert_equal 2, m.topics.size, "There should be 2 topics after creating the second one."
|
40
|
+
assert_kind_of RTM::Topic, t, "The created topic should really be one."
|
41
|
+
assert_kind_of RTM::TopicMap, m
|
42
|
+
assert_equal m, t.parent, "The Topic Map should be the parent of our new topic."
|
43
|
+
# The next tests may look a bit unneeded, but they at least also test the properties be available and initialized somehow.
|
44
|
+
assert_equal 0, t.item_identifiers.size, "New topic has no item_identifiers."
|
45
|
+
assert_equal 0, t.subject_identifiers.size, "New topic has no subject_identifiers."
|
46
|
+
assert_equal 0, t.subject_locators.size, "New topic has no subject_locators."
|
47
|
+
assert !t.valid?, "Without item identifiers nor subject identifiers the topic must not be valid."
|
48
|
+
assert_equal 0, t.names.size, "New topic has no names."
|
49
|
+
assert_equal 0, t.occurrences.size, "New topic has no occurrences."
|
50
|
+
assert_equal 0, t.roles_played.size, "New topic plays no roles."
|
51
|
+
assert_nil t.reified, "New topic does not reify a statement."
|
52
|
+
|
53
|
+
n = t.create_name
|
54
|
+
assert_equal 1, t.names.size, "The topic should have one name now."
|
55
|
+
assert_kind_of RTM::TopicName, n
|
56
|
+
assert_kind_of RTM::Topic, n.parent, "You won't believe but this should be a Topic and right now it not..."
|
57
|
+
# TODO the following assertion does not work - it crashes pp... but why?
|
58
|
+
#assert_equal t, n.parent, "The parent of the name should be the topic on which it was created."
|
59
|
+
assert_equal 0, n.item_identifiers.size, "I wonder if someone will ever read that."
|
60
|
+
assert_kind_of RTM::TopicName, n, "The topic name shoud be a TopicName... makes sence, he?"
|
61
|
+
assert_equal 0, n.variants.size, "According to Lars Heuer and Robert Barta that should always be 0, not only now."
|
62
|
+
assert_nil n.value, "We haven't set a value yet, where should it come from."
|
63
|
+
assert_nil n.type, "I am really tired of writing this stuff."
|
64
|
+
assert_equal 0, n.scope.size, "Should I really be more serious with this stuff?"
|
65
|
+
assert_nil n.reifier, "No, I guess not... who could ever stand that."
|
66
|
+
|
67
|
+
v = n.create_variant
|
68
|
+
assert_equal 1, n.variants.size, "The topic should have one name now."
|
69
|
+
assert_kind_of RTM::Variant, v
|
70
|
+
assert_kind_of RTM::TopicName, v.parent, "You won't believe but this should be a Topic and right now it not..."
|
71
|
+
# TODO the following assertion does not work - it crashes pp... but why?
|
72
|
+
#assert_equal t, v.parent, "The parent of the name should be the topic on which it was created."
|
73
|
+
assert_equal 0, v.item_identifiers.size, "I wonder if someone will ever read that."
|
74
|
+
assert_kind_of RTM::Variant, v, "The variant should be a Variant... makes sence, he?"
|
75
|
+
assert_nil v.value, "We haven't set a value yet, where should it come from."
|
76
|
+
assert_nil v.datatype, "No datatype set, yet."
|
77
|
+
assert_equal 0, v.scope.size, "Should I really be more serious with this stuff?"
|
78
|
+
assert_nil v.reifier, "No, I guess not... who could ever stand that."
|
79
|
+
assert !v.valid?
|
80
|
+
|
81
|
+
o = t.create_occurrence
|
82
|
+
assert_equal 1, t.occurrences.size, "The topic should have one name now."
|
83
|
+
assert_kind_of RTM::Occurrence, o
|
84
|
+
assert_kind_of RTM::Topic, o.parent, "You won't believe but this should be a Topic and right now it not..."
|
85
|
+
# TODO the following assertion does not work - it crashes pp... but why?
|
86
|
+
#assert_equal t, o.parent, "The parent of the name should be the topic on which it was created."
|
87
|
+
assert_equal 0, o.item_identifiers.size, "I wonder if someone will ever read that."
|
88
|
+
assert_kind_of RTM::Occurrence, o, "The occurrence shoud be a Occurrence... makes sence, he?"
|
89
|
+
assert_nil o.value, "We haven't set a value yet, where should it come from."
|
90
|
+
assert_nil o.type, "I am really tired of writing this stuff."
|
91
|
+
assert_nil o.datatype
|
92
|
+
assert_equal 0, n.scope.size, "Should I really be more serious with this stuff?"
|
93
|
+
assert_nil n.reifier, "No, I guess not... who could ever stand that."
|
94
|
+
|
95
|
+
a = m.create_association
|
96
|
+
assert_nil a.type
|
97
|
+
assert_equal 0, a.roles.size
|
98
|
+
assert_kind_of RTM::Association, a
|
99
|
+
assert_kind_of RTM::TopicMap, a.parent
|
100
|
+
assert_equal m, a.parent
|
101
|
+
assert_equal 0, a.scope.size
|
102
|
+
assert !a.valid?
|
103
|
+
|
104
|
+
r1 = a.create_role
|
105
|
+
assert_nil r1.type
|
106
|
+
assert_nil r1.player
|
107
|
+
assert_kind_of RTM::AssociationRole, r1
|
108
|
+
assert_kind_of RTM::Association, r1.parent
|
109
|
+
assert_equal 1, a.roles.size
|
110
|
+
|
111
|
+
|
112
|
+
t.item_identifiers << "nr1"
|
113
|
+
assert_equal 1, t.item_identifiers.size
|
114
|
+
fii = t.item_identifiers.first
|
115
|
+
assert_equal "http://rtm.rubyforge.org/tests/base_test#nr1", fii.to_s
|
116
|
+
assert_kind_of RTM::Locator, fii
|
117
|
+
assert_kind_of RTM::ItemIdentifier, fii #needed?
|
118
|
+
# TODO: invalidate cache/reload value somehow
|
119
|
+
#assert_equal 1, m.item_identifiers.size, "If you see this, it is probably because TopicMap#item_identifiers.size is cached which is wrong in this case."
|
120
|
+
|
121
|
+
t.subject_identifiers << "si1"
|
122
|
+
fsi = t.subject_identifiers.first
|
123
|
+
assert_equal "si1", fsi.to_s
|
124
|
+
assert_kind_of RTM::Locator, fsi
|
125
|
+
assert_kind_of RTM::SubjectIdentifier, fsi #needed?
|
126
|
+
|
127
|
+
t.subject_locators << "sl1"
|
128
|
+
fsl = t.subject_locators.first
|
129
|
+
assert_equal "sl1", fsl.to_s
|
130
|
+
assert_kind_of RTM::Locator, fsl
|
131
|
+
assert_kind_of RTM::SubjectLocator, fsl #needed?
|
132
|
+
|
133
|
+
# create roles with topics
|
134
|
+
# some more stuff.
|
135
|
+
|
136
|
+
|
137
|
+
# to be in associations_test later:
|
138
|
+
tm = RTM.create "urn:/associations_test"
|
139
|
+
a1 = tm.create_association "urn:/assoc_type_with_absolute_uri"
|
140
|
+
assert_not_nil a1.type
|
141
|
+
assert_equal a1.type, tm.get("urn:/assoc_type_with_absolute_uri")
|
142
|
+
|
143
|
+
a2 = tm.create_association :type => "urn:/assoc_type_with_absolute_uri_using_hash"
|
144
|
+
assert_not_nil a2.type
|
145
|
+
assert_equal a2.type, tm.get("urn:/assoc_type_with_absolute_uri_using_hash")
|
146
|
+
|
147
|
+
a3 = tm.create_association "relative_type"
|
148
|
+
assert_not_nil a3.type
|
149
|
+
assert_equal a3.type, tm.get("relative_type")
|
150
|
+
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|