rdf_context 0.4.2 → 0.4.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/History.txt +3 -0
- data/VERSION +1 -1
- data/lib/rdf_context/conjunctive_graph.rb +1 -1
- data/lib/rdf_context/graph.rb +2 -2
- data/lib/rdf_context/rdfxmlparser.rb +0 -5
- data/lib/rdf_context/store/abstract_sql_store.rb +13 -7
- data/lib/rdf_context/store/abstract_store.rb +9 -0
- data/lib/rdf_context/store/list_store.rb +1 -5
- data/spec/conjunctive_graph_spec.rb +6 -0
- data/spec/graph_spec.rb +5 -0
- data/spec/list_store_spec.rb +1 -2
- data/spec/literal_spec.rb +17 -20
- data/spec/memory_store_spec.rb +1 -12
- data/spec/rdfxml_spec.rb +2 -2
- data/spec/sqlite3_store_spec.rb +26 -8
- data/spec/store_helper.rb +59 -29
- metadata +1 -1
data/History.txt
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
@@ -15,7 +15,7 @@ module RdfContext
|
|
15
15
|
# Store for ConjunctiveGraph must support contexts.
|
16
16
|
def initialize(options = {})
|
17
17
|
unless options[:store] && options[:store].context_aware?
|
18
|
-
raise GraphException.new("
|
18
|
+
raise GraphException.new("ConjunctiveGraph requires store supporting contexts")
|
19
19
|
end
|
20
20
|
|
21
21
|
super(:identifier => options[:store].identifier, :store => options[:store])
|
data/lib/rdf_context/graph.rb
CHANGED
@@ -72,8 +72,8 @@ module RdfContext
|
|
72
72
|
#
|
73
73
|
# Might be necessary for stores that require opening a connection to a
|
74
74
|
# database or acquiring some resource.
|
75
|
-
def open(configuration
|
76
|
-
@store.open(configuration
|
75
|
+
def open(configuration = {})
|
76
|
+
@store.open(configuration)
|
77
77
|
end
|
78
78
|
|
79
79
|
# Close the graph store
|
@@ -149,11 +149,6 @@ module RdfContext
|
|
149
149
|
end
|
150
150
|
|
151
151
|
private
|
152
|
-
# Is the node rdf:RDF?
|
153
|
-
def is_rdf_root? (node)
|
154
|
-
node.name == "RDF" && node.namespace.href == RDF_NS.uri.to_s
|
155
|
-
end
|
156
|
-
|
157
152
|
# XML nodeElement production
|
158
153
|
#
|
159
154
|
# @param [XML Element] el:: XMl Element to parse
|
@@ -39,9 +39,6 @@ module RdfContext
|
|
39
39
|
@bnodeCache = {}
|
40
40
|
@uriCache = {}
|
41
41
|
|
42
|
-
@context_aware = true
|
43
|
-
@formula_aware = true
|
44
|
-
@transaction_aware = true
|
45
42
|
@autocommit_default = true
|
46
43
|
|
47
44
|
raise StoreException.new("Identifier must be nil or a URIRef") if identifier && !identifier.is_a?(URIRef)
|
@@ -51,6 +48,15 @@ module RdfContext
|
|
51
48
|
|
52
49
|
@db = configuration.empty? ? nil : open(configuration)
|
53
50
|
end
|
51
|
+
|
52
|
+
# Supports contexts
|
53
|
+
def context_aware?; true; end
|
54
|
+
|
55
|
+
# Supports formulae
|
56
|
+
def formula_aware?; true; end
|
57
|
+
|
58
|
+
# Supports transactions
|
59
|
+
def transaction_aware?; true; end
|
54
60
|
|
55
61
|
def close(commit_pending_transactions = false)
|
56
62
|
@db.commit if commit_pending_transactions && @db.transaction_active?
|
@@ -525,9 +531,9 @@ module RdfContext
|
|
525
531
|
|
526
532
|
# List of namespace bindings, as a hash
|
527
533
|
def nsbinding
|
528
|
-
namespaces =
|
534
|
+
namespaces = {}
|
529
535
|
executeSQL("SELECT prefix, uri FROM #{namespace_binds}") do |row|
|
530
|
-
namespaces
|
536
|
+
namespaces[row[0]] = Namespace.new(row[1], row[0])
|
531
537
|
end
|
532
538
|
namespaces
|
533
539
|
end
|
@@ -727,11 +733,11 @@ module RdfContext
|
|
727
733
|
end
|
728
734
|
|
729
735
|
def buildLitDTypeClause(obj,tableName)
|
730
|
-
"#{tableName}.objDatatype='#{obj.encoding.value}'" if obj.is_a?(Literal) && obj.encoding
|
736
|
+
["#{tableName}.objDatatype='#{obj.encoding.value}'"] if obj.is_a?(Literal) && obj.encoding
|
731
737
|
end
|
732
738
|
|
733
739
|
def buildLitLanguageClause(obj,tableName)
|
734
|
-
"#{tableName}.objDatatype='#{obj.lang}'" if obj.is_a?(Literal) && obj.lang
|
740
|
+
["#{tableName}.objDatatype='#{obj.lang}'"] if obj.is_a?(Literal) && obj.lang
|
735
741
|
end
|
736
742
|
|
737
743
|
# Stubs for Clause Functions that are overridden by specific implementations (MySQL vs SQLite for instance)
|
@@ -11,6 +11,10 @@ module RdfContext
|
|
11
11
|
@identifier = identifier || BNode.new
|
12
12
|
end
|
13
13
|
|
14
|
+
def context_aware?; false; end
|
15
|
+
def formula_aware?; false; end
|
16
|
+
def transaction_aware?; false; end
|
17
|
+
|
14
18
|
# Interfaces that must be implemented
|
15
19
|
def triples(triple, context = nil) # :yields: triple, context
|
16
20
|
raise StoreException, "not implemented"
|
@@ -22,6 +26,11 @@ module RdfContext
|
|
22
26
|
def inspect
|
23
27
|
"#{self.class}[identifier=#{identifier.inspect}]"
|
24
28
|
end
|
29
|
+
|
30
|
+
def destroy(configuration = {}); end
|
31
|
+
def open(configuration = {}); end
|
32
|
+
def commit; end
|
33
|
+
def rollback; end
|
25
34
|
|
26
35
|
# Bind namespace to store, returns bound namespace
|
27
36
|
def bind(namespace)
|
@@ -25,11 +25,7 @@ module RdfContext
|
|
25
25
|
# If the triple does not provide a context attribute, removes the triple
|
26
26
|
# from all contexts.
|
27
27
|
def remove(triple, context, quoted = false)
|
28
|
-
|
29
|
-
@triples.delete(triple)
|
30
|
-
else
|
31
|
-
@triples = []
|
32
|
-
end
|
28
|
+
@triples.delete(triple)
|
33
29
|
end
|
34
30
|
|
35
31
|
# Check to see if this graph contains the specified triple
|
@@ -9,6 +9,12 @@ describe "ConjunctiveGraph" do
|
|
9
9
|
|
10
10
|
subject { ConjunctiveGraph.new(:store => @store)}
|
11
11
|
|
12
|
+
it "should require store supporting contexts" do
|
13
|
+
lambda do
|
14
|
+
ConjunctiveGraph.new(:store => ListStore.new)
|
15
|
+
end.should raise_error(GraphException, "ConjunctiveGraph requires store supporting contexts")
|
16
|
+
end
|
17
|
+
|
12
18
|
it "should should have same identifier as store" do
|
13
19
|
subject.identifier.should == @identifier
|
14
20
|
end
|
data/spec/graph_spec.rb
CHANGED
@@ -76,6 +76,11 @@ describe "Graphs" do
|
|
76
76
|
subject.add(Triple.new(@ex.a, @ex.b, @ex.c), Triple.new(@ex.a, @ex.b, @ex.d))
|
77
77
|
subject.size.should == 2
|
78
78
|
end
|
79
|
+
|
80
|
+
it "should freeze when destroyed" do
|
81
|
+
subject.destroy
|
82
|
+
subject.frozen?.should be_true
|
83
|
+
end
|
79
84
|
|
80
85
|
describe "with identifier" do
|
81
86
|
before(:all) { @identifier = URIRef.new("http://foo.bar") }
|
data/spec/list_store_spec.rb
CHANGED
@@ -3,8 +3,7 @@ require File.join(File.dirname(__FILE__), 'store_helper')
|
|
3
3
|
|
4
4
|
describe "List Store" do
|
5
5
|
before(:all) do
|
6
|
-
|
7
|
-
@ctx = @identifier
|
6
|
+
@identifier = URIRef.new("http://identifier")
|
8
7
|
end
|
9
8
|
|
10
9
|
subject { ListStore.new(@identifier) }
|
data/spec/literal_spec.rb
CHANGED
@@ -290,25 +290,22 @@ describe "Literals: " do
|
|
290
290
|
end
|
291
291
|
end
|
292
292
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
# lang.hash.class.should == Fixnum
|
311
|
-
# end
|
312
|
-
# end
|
293
|
+
describe "Encodings" do
|
294
|
+
specify "integer" do
|
295
|
+
Literal::Encoding.integer.should == Literal::Encoding.new("http://www.w3.org/2001/XMLSchema#int")
|
296
|
+
end
|
297
|
+
specify "float" do
|
298
|
+
Literal::Encoding.float.should == Literal::Encoding.new("http://www.w3.org/2001/XMLSchema#float")
|
299
|
+
end
|
300
|
+
specify "string" do
|
301
|
+
Literal::Encoding.string.should == Literal::Encoding.new("http://www.w3.org/2001/XMLSchema#string")
|
302
|
+
end
|
303
|
+
specify "xmlliteral" do
|
304
|
+
Literal::Encoding.xmlliteral.should == Literal::XMLLiteral.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral")
|
305
|
+
end
|
306
|
+
specify "null" do
|
307
|
+
Literal::Encoding.the_null_encoding.should == Literal::Null.new(nil)
|
308
|
+
end
|
309
|
+
end
|
313
310
|
|
314
311
|
end
|
data/spec/memory_store_spec.rb
CHANGED
@@ -3,21 +3,10 @@ require File.join(File.dirname(__FILE__), 'store_helper')
|
|
3
3
|
|
4
4
|
describe "Memory Store" do
|
5
5
|
before(:all) do
|
6
|
-
|
7
|
-
@ctx = @identifier
|
6
|
+
@identifier = URIRef.new("http://identifier")
|
8
7
|
end
|
9
8
|
|
10
9
|
subject { MemoryStore.new(@identifier) }
|
11
10
|
it_should_behave_like "Store"
|
12
11
|
it_should_behave_like "Context Aware Store"
|
13
|
-
|
14
|
-
|
15
|
-
describe "with context" do
|
16
|
-
before(:all) do
|
17
|
-
@ctx = URIRef.new("http://context")
|
18
|
-
end
|
19
|
-
|
20
|
-
it_should_behave_like "Store"
|
21
|
-
it_should_behave_like "Context Aware Store"
|
22
|
-
end
|
23
12
|
end
|
data/spec/rdfxml_spec.rb
CHANGED
@@ -321,11 +321,11 @@ EOF
|
|
321
321
|
include RdfXMLHelper
|
322
322
|
|
323
323
|
def self.positive_tests
|
324
|
-
|
324
|
+
RdfXMLHelper::TestCase.positive_parser_tests rescue []
|
325
325
|
end
|
326
326
|
|
327
327
|
def self.negative_tests
|
328
|
-
|
328
|
+
RdfXMLHelper::TestCase.negative_parser_tests rescue []
|
329
329
|
end
|
330
330
|
|
331
331
|
# Negative parser tests should raise errors.
|
data/spec/sqlite3_store_spec.rb
CHANGED
@@ -6,7 +6,6 @@ describe "SQLite3 Store" do
|
|
6
6
|
Dir.mkdir(File.dirname(__FILE__) + "/tmp")
|
7
7
|
@dbfile = File.join(File.dirname(__FILE__), "tmp", "sqlite3.db")
|
8
8
|
@identifier = URIRef.new("http://identifier")
|
9
|
-
@ctx = @identifier
|
10
9
|
end
|
11
10
|
|
12
11
|
before(:each) do
|
@@ -30,12 +29,31 @@ describe "SQLite3 Store" do
|
|
30
29
|
File.exists?(@dbfile).should be_false
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
it "should close db" do
|
33
|
+
subject.close
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should find contexts with type" do
|
37
|
+
triple = Triple.new("http://foo", RDF_TYPE, "http://baz")
|
38
|
+
subject.add(triple, nil)
|
39
|
+
subject.contexts(triple).length.should == 1
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should find triples with typed literal" do
|
43
|
+
triple = Triple.new("http://foo", RDF_TYPE, Literal.build_from(1.1))
|
44
|
+
subject.add(triple, nil)
|
45
|
+
subject.contexts(triple).length.should == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should find triples with untyped literal and lang" do
|
49
|
+
triple = Triple.new("http://foo", RDF_TYPE, Literal.untyped("foo", "en-US"))
|
50
|
+
subject.add(triple, nil)
|
51
|
+
subject.contexts(triple).length.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should find contexts patern triple" do
|
55
|
+
triple = Triple.new("http://foo", RDF_TYPE, "http://baz")
|
56
|
+
subject.add(triple, nil)
|
57
|
+
subject.contexts(Triple.new(nil, nil, nil)).length.should == 1
|
40
58
|
end
|
41
59
|
end
|
data/spec/store_helper.rb
CHANGED
@@ -9,8 +9,8 @@ shared_examples_for "Store" do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should allow you to add a triple" do
|
12
|
-
subject.add(Triple.new(@ex.a, @ex.b, @ex.c),
|
13
|
-
subject.add(Triple.new(@ex.a, @ex.b, @ex.d),
|
12
|
+
subject.add(Triple.new(@ex.a, @ex.b, @ex.c), nil)
|
13
|
+
subject.add(Triple.new(@ex.a, @ex.b, @ex.d), nil)
|
14
14
|
subject.size.should == 2
|
15
15
|
end
|
16
16
|
|
@@ -23,16 +23,38 @@ shared_examples_for "Store" do
|
|
23
23
|
subject.identifier.should == @identifier
|
24
24
|
end
|
25
25
|
|
26
|
+
describe "namespaces" do
|
27
|
+
before(:each) do
|
28
|
+
subject.bind(@ex)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return namespace by prefix" do
|
32
|
+
subject.namespace(@ex.prefix).should == @ex
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should return prefix by uri" do
|
36
|
+
subject.prefix(@ex.uri).should == @ex.prefix
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should bind namespace" do
|
40
|
+
subject.bind(@foaf).should == @foaf
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return all namespaces" do
|
44
|
+
subject.nsbinding.should == { @ex.prefix => @ex}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
26
48
|
describe "with triples" do
|
27
49
|
before(:each) do
|
28
|
-
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.jane),
|
29
|
-
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.rick),
|
30
|
-
subject.add(Triple.new(@ex.jane, @foaf.knows, @ex.rick),
|
50
|
+
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.jane), nil)
|
51
|
+
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.rick), nil)
|
52
|
+
subject.add(Triple.new(@ex.jane, @foaf.knows, @ex.rick), nil)
|
31
53
|
subject.bind(@foaf)
|
32
54
|
end
|
33
55
|
|
34
56
|
it "should detect included triple" do
|
35
|
-
subject.contains?(Triple.new(@ex.john, @foaf.knows, @ex.jane),
|
57
|
+
subject.contains?(Triple.new(@ex.john, @foaf.knows, @ex.jane), nil).should be_true
|
36
58
|
end
|
37
59
|
|
38
60
|
it "should contain different triple paterns" do
|
@@ -46,8 +68,8 @@ shared_examples_for "Store" do
|
|
46
68
|
Triple.new(URIRef.new("http://foo"),URIRef.new("http://bar"),Literal.typed("gregg", "http://www.w3.org/2001/XMLSchema#string")),
|
47
69
|
Triple.new(URIRef.new("http://foo"),URIRef.new("http://bar"),"gregg"),
|
48
70
|
].each do |t|
|
49
|
-
subject.add(t,
|
50
|
-
subject.contains?(t,
|
71
|
+
subject.add(t, nil)
|
72
|
+
subject.contains?(t, nil)
|
51
73
|
end
|
52
74
|
end
|
53
75
|
|
@@ -56,12 +78,12 @@ shared_examples_for "Store" do
|
|
56
78
|
end
|
57
79
|
|
58
80
|
it "should allow you to select resources" do
|
59
|
-
subject.triples(Triple.new(@ex.john, nil, nil),
|
81
|
+
subject.triples(Triple.new(@ex.john, nil, nil), nil).size.should == 2
|
60
82
|
end
|
61
83
|
|
62
84
|
it "should allow iteration" do
|
63
85
|
count = 0
|
64
|
-
subject.triples(Triple.new(nil, nil, nil),
|
86
|
+
subject.triples(Triple.new(nil, nil, nil), nil) do |t, context|
|
65
87
|
count = count + 1
|
66
88
|
t.class.should == Triple
|
67
89
|
end
|
@@ -70,7 +92,7 @@ shared_examples_for "Store" do
|
|
70
92
|
|
71
93
|
it "should allow iteration over a particular subject" do
|
72
94
|
count = 0
|
73
|
-
subject.triples(Triple.new(@ex.john, nil, nil),
|
95
|
+
subject.triples(Triple.new(@ex.john, nil, nil), nil) do |t, context|
|
74
96
|
count = count + 1
|
75
97
|
t.class.should == Triple
|
76
98
|
end
|
@@ -79,7 +101,7 @@ shared_examples_for "Store" do
|
|
79
101
|
|
80
102
|
it "should allow iteration over a particular predicate" do
|
81
103
|
count = 0
|
82
|
-
subject.triples(Triple.new(nil, @foaf.knows, nil),
|
104
|
+
subject.triples(Triple.new(nil, @foaf.knows, nil), nil) do |t, context|
|
83
105
|
count = count + 1
|
84
106
|
t.class.should == Triple
|
85
107
|
end
|
@@ -88,7 +110,7 @@ shared_examples_for "Store" do
|
|
88
110
|
|
89
111
|
it "should allow iteration over a particular object" do
|
90
112
|
count = 0
|
91
|
-
subject.triples(Triple.new(nil, nil, @ex.jane),
|
113
|
+
subject.triples(Triple.new(nil, nil, @ex.jane), nil) do |t, context|
|
92
114
|
count = count + 1
|
93
115
|
t.class.should == Triple
|
94
116
|
end
|
@@ -96,9 +118,9 @@ shared_examples_for "Store" do
|
|
96
118
|
end
|
97
119
|
|
98
120
|
it "should find combinations" do
|
99
|
-
subject.triples(Triple.new(@ex.john, @foaf.knows, nil),
|
100
|
-
subject.triples(Triple.new(@ex.john, nil, @ex.jane),
|
101
|
-
subject.triples(Triple.new(nil, @foaf.knows, @ex.jane),
|
121
|
+
subject.triples(Triple.new(@ex.john, @foaf.knows, nil), nil).length.should == 2
|
122
|
+
subject.triples(Triple.new(@ex.john, nil, @ex.jane), nil).length.should == 1
|
123
|
+
subject.triples(Triple.new(nil, @foaf.knows, @ex.jane), nil).length.should == 1
|
102
124
|
end
|
103
125
|
|
104
126
|
it "should retrieve indexed item" do
|
@@ -113,20 +135,19 @@ shared_examples_for "Store" do
|
|
113
135
|
|
114
136
|
describe "with typed triples" do
|
115
137
|
before(:each) do
|
116
|
-
subject.add(Triple.new(@ex.john, RDF_TYPE, @foaf.Person),
|
117
|
-
subject.add(Triple.new(@ex.jane, RDF_TYPE, @foaf.Person),
|
118
|
-
subject.add(Triple.new(@ex.rick, RDF_TYPE, @foaf.Person),
|
119
|
-
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.jane),
|
120
|
-
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.
|
121
|
-
subject.add(Triple.new(@ex.
|
122
|
-
subject.add(Triple.new(@ex.jane, @foaf.knows, @ex.rick), @ctx)
|
138
|
+
subject.add(Triple.new(@ex.john, RDF_TYPE, @foaf.Person), nil)
|
139
|
+
subject.add(Triple.new(@ex.jane, RDF_TYPE, @foaf.Person), nil)
|
140
|
+
subject.add(Triple.new(@ex.rick, RDF_TYPE, @foaf.Person), nil)
|
141
|
+
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.jane), nil)
|
142
|
+
subject.add(Triple.new(@ex.john, @foaf.knows, @ex.rick), nil)
|
143
|
+
subject.add(Triple.new(@ex.jane, @foaf.knows, @ex.rick), nil)
|
123
144
|
subject.bind(@foaf)
|
124
145
|
subject.bind(@ex)
|
125
146
|
end
|
126
147
|
|
127
148
|
it "should find subjects by type" do
|
128
149
|
count = 0
|
129
|
-
subject.triples(Triple.new(nil, RDF_TYPE, nil),
|
150
|
+
subject.triples(Triple.new(nil, RDF_TYPE, nil), nil) do |triple, ctx|
|
130
151
|
count += 1
|
131
152
|
[@ex.john, @ex.jane, @ex.rick].should include(triple.subject)
|
132
153
|
triple.predicate.should == RDF_TYPE
|
@@ -134,15 +155,19 @@ shared_examples_for "Store" do
|
|
134
155
|
end
|
135
156
|
count.should == 3
|
136
157
|
end
|
158
|
+
|
159
|
+
it "should remove types" do
|
160
|
+
subject.remove(Triple.new(nil, RDF_TYPE, nil), nil)
|
161
|
+
subject.size.should == 3
|
162
|
+
end
|
137
163
|
end
|
138
164
|
|
139
165
|
it "should remove a triple" do
|
140
|
-
subject.add(Triple.new(@ex.john, RDF_TYPE, @foaf.Person),
|
141
|
-
subject.size
|
142
|
-
subject.remove(Triple.new(@ex.john, RDF_TYPE, @foaf.Person),
|
143
|
-
subject.size
|
166
|
+
subject.add(Triple.new(@ex.john, RDF_TYPE, @foaf.Person), nil)
|
167
|
+
subject.size.should == 1
|
168
|
+
subject.remove(Triple.new(@ex.john, RDF_TYPE, @foaf.Person), nil)
|
169
|
+
subject.size.should == 0
|
144
170
|
end
|
145
|
-
|
146
171
|
end
|
147
172
|
|
148
173
|
shared_examples_for "Context Aware Store" do
|
@@ -189,6 +214,11 @@ shared_examples_for "Context Aware Store" do
|
|
189
214
|
subject.contexts.length.should == 2
|
190
215
|
end
|
191
216
|
|
217
|
+
it "should find contexts containing triple" do
|
218
|
+
subject.add(@triple, @ctx1)
|
219
|
+
subject.contexts(@triple).should == [@ctx1]
|
220
|
+
end
|
221
|
+
|
192
222
|
it "should remove from specific context" do
|
193
223
|
subject.add(@triple, @ctx1)
|
194
224
|
subject.add(@triple, @ctx2)
|