dbd 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +8 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +97 -0
- data/Rakefile +1 -0
- data/dbd.gemspec +30 -0
- data/docs/rationale.md +17 -0
- data/docs/stories/001_create_a_fact.txt +15 -0
- data/docs/stories/002_create_a_facts_collection.txt +14 -0
- data/docs/stories/003_create_a_fact_origin.txt +15 -0
- data/docs/stories/004_create_fact_origins_collection.txt +8 -0
- data/docs/stories/005_CSV_export_the_graph.txt +18 -0
- data/docs/stories/006_refactor_fact_origin_to_provenance_fact.txt +20 -0
- data/docs/stories/007_rename_property_to_predicate.txt +6 -0
- data/docs/stories/008_testing_different_ruby_versions.txt +7 -0
- data/docs/stories/009_build_and_store_resources_with_provenance.txt +38 -0
- data/docs/stories/010_provenance_fact_properties_from_provenance_ontology.txt +10 -0
- data/docs/test.rb +32 -0
- data/lib/dbd.rb +13 -0
- data/lib/dbd/errors.rb +11 -0
- data/lib/dbd/fact.rb +182 -0
- data/lib/dbd/fact/collection.rb +60 -0
- data/lib/dbd/fact/id.rb +19 -0
- data/lib/dbd/fact/subject.rb +21 -0
- data/lib/dbd/graph.rb +47 -0
- data/lib/dbd/helpers/ordered_set_collection.rb +86 -0
- data/lib/dbd/helpers/uuid.rb +33 -0
- data/lib/dbd/provenance_fact.rb +76 -0
- data/lib/dbd/provenance_resource.rb +54 -0
- data/lib/dbd/rdf.rb +9 -0
- data/lib/dbd/repo.rb +8 -0
- data/lib/dbd/repo/neo4j_repo.rb +4 -0
- data/lib/dbd/repo/neo4j_repo/base.rb +55 -0
- data/lib/dbd/resource.rb +117 -0
- data/lib/dbd/version.rb +3 -0
- data/spec/factories/fact.rb +76 -0
- data/spec/factories/provenance_fact.rb +34 -0
- data/spec/factories/provenance_resource.rb +16 -0
- data/spec/factories/resource.rb +17 -0
- data/spec/lib/dbd/fact/collection_spec.rb +236 -0
- data/spec/lib/dbd/fact/id_spec.rb +19 -0
- data/spec/lib/dbd/fact/subject_spec.rb +19 -0
- data/spec/lib/dbd/fact_spec.rb +217 -0
- data/spec/lib/dbd/graph_spec.rb +214 -0
- data/spec/lib/dbd/helpers/ordered_set_collection_spec.rb +88 -0
- data/spec/lib/dbd/helpers/uuid_spec.rb +15 -0
- data/spec/lib/dbd/provenance_fact_spec.rb +108 -0
- data/spec/lib/dbd/provenance_resource_spec.rb +77 -0
- data/spec/lib/dbd/rdf_base_spec.rb +39 -0
- data/spec/lib/dbd/repo/neo4j_repo/base_spec.rb +85 -0
- data/spec/lib/dbd/repo/neo4j_repo/performance_spec.rb +40 -0
- data/spec/lib/dbd/resource_spec.rb +166 -0
- data/spec/spec_helper.rb +19 -0
- metadata +272 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbd
|
4
|
+
describe Graph do
|
5
|
+
|
6
|
+
def new_subject
|
7
|
+
Fact.new_subject
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:data_fact) { Factories::Fact.data_fact(new_subject, new_subject) }
|
11
|
+
let(:fact_no_subject) { Factories::Fact.data_fact(new_subject, nil) }
|
12
|
+
let(:fact_no_provenance) { Factories::Fact.data_fact(nil, new_subject) }
|
13
|
+
|
14
|
+
let(:provenance_facts) { Factories::Fact::Collection.provenance_facts(new_subject) }
|
15
|
+
let(:provenance_fact_1) { provenance_facts.first }
|
16
|
+
let(:fact_2_3) { Factories::Fact::Collection.fact_2_3(provenance_fact_1.subject) }
|
17
|
+
|
18
|
+
let(:subject_regexp) { Fact::Subject.regexp }
|
19
|
+
let(:id_regexp) { Fact::ID.regexp }
|
20
|
+
|
21
|
+
describe "create a graph" do
|
22
|
+
it "does not fail" do
|
23
|
+
described_class.new # should_not raise_error
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "<< " do
|
28
|
+
describe "a Fact" do
|
29
|
+
it "a data_fact does not fail" do
|
30
|
+
subject << data_fact
|
31
|
+
end
|
32
|
+
|
33
|
+
it "a provenance_fact does not fail" do
|
34
|
+
subject << provenance_fact_1
|
35
|
+
end
|
36
|
+
|
37
|
+
it "two facts does not fail" do
|
38
|
+
subject << provenance_fact_1
|
39
|
+
subject << data_fact
|
40
|
+
end
|
41
|
+
|
42
|
+
it "fact with missing subject raises FactError" do
|
43
|
+
lambda { subject << fact_no_subject } . should raise_error FactError
|
44
|
+
end
|
45
|
+
|
46
|
+
it "fact with missing provenance raises FactError" do
|
47
|
+
lambda { subject << fact_no_provenance } . should raise_error FactError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "sets the time_stamp and adds 2 nanoseconds if needed" do
|
52
|
+
it "sets the time_stamp" do
|
53
|
+
data_fact.time_stamp.should be_nil # assert pre condition
|
54
|
+
subject << data_fact
|
55
|
+
subject.first.time_stamp.should be_a(Time)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "sets a slightly higher time_stamp if smaller or equal then newest_time_stamp" do
|
59
|
+
subject
|
60
|
+
subject.newest_time_stamp
|
61
|
+
far_future = Time.new(2200,1,1,12,0,0).utc
|
62
|
+
subject.stub(:newest_time_stamp).and_return(far_future)
|
63
|
+
subject << data_fact
|
64
|
+
subject.first.time_stamp.should > far_future
|
65
|
+
subject.first.time_stamp.should < far_future + 0.000_000_005
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#to_CSV with only provenance_facts" do
|
71
|
+
before do
|
72
|
+
provenance_facts.each_with_index do |provenance_fact, index|
|
73
|
+
subject << provenance_fact
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns a string" do
|
78
|
+
subject.to_CSV.should be_a(String)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns a string in UTF-8 encoding" do
|
82
|
+
subject.to_CSV.encoding.should == Encoding::UTF_8
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns a string with comma's" do
|
86
|
+
subject.to_CSV.should match(/\A"[^",]+","[^",]+","[^",]*","[^",]+"/)
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "with a single provenance_fact collection" do
|
90
|
+
it "has three logical lines (but one with embedded newline)" do
|
91
|
+
subject.to_CSV.lines.count.should == 4
|
92
|
+
end
|
93
|
+
|
94
|
+
it "ends with a newline" do
|
95
|
+
subject.to_CSV.lines.to_a.last[-1].should == "\n"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "has all attributes of the provenance_fact_collection" do
|
100
|
+
|
101
|
+
let(:first_line) do
|
102
|
+
subject.to_CSV.lines.to_a.first.chomp
|
103
|
+
end
|
104
|
+
|
105
|
+
it "has id (a Fact::ID) as first value" do
|
106
|
+
first_line.split(',')[0].gsub(/"/, '').should match(id_regexp)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "has time_stamp as second value" do
|
110
|
+
first_line.split(',')[1].should match(/"\d{4}-\d\d-\d\d \d\d:\d\d:\d\d UTC"/)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "has an empty third value (signature of a provenance_fact)" do
|
114
|
+
first_line.split(',')[2].should == "\"\""
|
115
|
+
end
|
116
|
+
|
117
|
+
it "has subject as 4th value" do
|
118
|
+
first_line.split(',')[3].gsub(/"/, '').should match(subject_regexp)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "has data_predicate as 5th value" do
|
122
|
+
first_line.split(',')[4].should == '"https://data.vandenabeele.com/ontologies/provenance#context"'
|
123
|
+
end
|
124
|
+
|
125
|
+
it "has object as 6th value" do
|
126
|
+
first_line.split(',')[5].should == '"public"'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "handles comma, double quote and newline correctly" do
|
131
|
+
it "has original_source with special characters and double quote escaped" do
|
132
|
+
subject.to_CSV.should match(/"this has a comma , a newline \n and a double quote """/)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#to_CSV with only facts" do
|
138
|
+
before do
|
139
|
+
fact_2_3.each_with_index do |fact, index|
|
140
|
+
subject << fact
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
it "returns a string" do
|
145
|
+
subject.to_CSV.should be_a(String)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns a string in UTF-8 encoding" do
|
149
|
+
subject.to_CSV.encoding.should == Encoding::UTF_8
|
150
|
+
end
|
151
|
+
|
152
|
+
it "returns a string with comma's" do
|
153
|
+
subject.to_CSV.should match(/\A"[^",]+","[^",]+","[^",]+"/)
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "with a single fact collection" do
|
157
|
+
it "has two lines" do
|
158
|
+
subject.to_CSV.lines.count.should == 2
|
159
|
+
end
|
160
|
+
|
161
|
+
it "ends with a newline" do
|
162
|
+
subject.to_CSV.lines.to_a.last[-1].should == "\n"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "has all attributes of the fact_collection" do
|
167
|
+
|
168
|
+
let(:first_line) do
|
169
|
+
subject.to_CSV.lines.to_a.first.chomp
|
170
|
+
end
|
171
|
+
|
172
|
+
it "has id (a Fact::ID) as first value" do
|
173
|
+
first_line.split(',')[0].gsub(/"/, '').should match(id_regexp)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "has time_stamp as second value" do
|
177
|
+
first_line.split(',')[1].should match(/"\d{4}-\d\d-\d\d \d\d:\d\d:\d\d UTC"/)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "has provenance_fact_1.subject as third value" do
|
181
|
+
first_line.split(',')[2].should == "\"#{provenance_fact_1.subject.to_s}\""
|
182
|
+
end
|
183
|
+
|
184
|
+
it "has subject as 4th value" do
|
185
|
+
first_line.split(',')[3].gsub(/"/, '').should match(subject_regexp)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "has data_predicate as 5th value" do
|
189
|
+
first_line.split(',')[4].should == '"http://example.org/test/name"'
|
190
|
+
end
|
191
|
+
|
192
|
+
it "has object as 6th value" do
|
193
|
+
first_line.split(',')[5].should == '"Mandela"'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "#to_CSV with provenance_facts and facts" do
|
199
|
+
|
200
|
+
before do
|
201
|
+
provenance_facts.each do |provenance_fact|
|
202
|
+
subject << provenance_fact
|
203
|
+
end
|
204
|
+
fact_2_3.each do |fact|
|
205
|
+
subject << fact
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
it "has six lines" do
|
210
|
+
subject.to_CSV.lines.count.should == 6
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbd
|
4
|
+
module Helpers
|
5
|
+
describe OrderedSetCollection do
|
6
|
+
|
7
|
+
let(:element_1) {:element_1}
|
8
|
+
let(:element_2) {:element_2}
|
9
|
+
let(:subject) do
|
10
|
+
o = Object.new
|
11
|
+
o.extend(described_class)
|
12
|
+
o.send(:initialize)
|
13
|
+
o
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "create an elements collection" do
|
17
|
+
it "the collection is not an array" do
|
18
|
+
# do not derive from Ruby standard classes
|
19
|
+
subject.should_not be_a(Array)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "accessor functions" do
|
24
|
+
it "the collection has Enumerable methods" do
|
25
|
+
subject.map #should_not raise_exception
|
26
|
+
subject.first #should_not raise_exception
|
27
|
+
end
|
28
|
+
|
29
|
+
it "<< adds the element" do
|
30
|
+
subject << element_1
|
31
|
+
subject.count.should == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns self to allow chaining" do
|
35
|
+
(subject << element_1).should == subject
|
36
|
+
end
|
37
|
+
|
38
|
+
it "other functions (e.g. pop) do not work" do
|
39
|
+
lambda {subject.pop} . should raise_exception NoMethodError
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "add_and_return_index returns the index of the inserted element" do
|
43
|
+
|
44
|
+
let(:internal_collection) do
|
45
|
+
subject.instance_variable_get("@internal_collection")
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:index) do
|
49
|
+
described_class.add_and_return_index(element_1, internal_collection)
|
50
|
+
end
|
51
|
+
|
52
|
+
before(:each) { index }
|
53
|
+
|
54
|
+
it "works for 1 element" do
|
55
|
+
index.should == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
it "works for 2 elements" do
|
59
|
+
index_2 = described_class.add_and_return_index(element_2, internal_collection)
|
60
|
+
index_2.should == 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "last" do
|
65
|
+
it "returns the last element" do
|
66
|
+
subject << element_1
|
67
|
+
subject << element_2
|
68
|
+
subject.last.should == element_2
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "size" do
|
73
|
+
it "returns the last element" do
|
74
|
+
subject << element_1
|
75
|
+
subject << element_2
|
76
|
+
subject.size.should == 2
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "on empty collection" do
|
82
|
+
it "#last returns nil" do
|
83
|
+
subject.last.should be_nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbd
|
4
|
+
module Helpers
|
5
|
+
describe UUID do
|
6
|
+
it ".regex" do
|
7
|
+
'12345678-abcd-4567-89ab-0123456789ab'.should match(UUID.regexp)
|
8
|
+
end
|
9
|
+
|
10
|
+
it ".new creates a new random UUID" do
|
11
|
+
described_class.new.to_s.should match(UUID.regexp)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbd
|
4
|
+
describe ProvenanceFact do
|
5
|
+
|
6
|
+
let(:subject) { described_class.new_subject }
|
7
|
+
let(:id_class) { described_class.new_id.class }
|
8
|
+
|
9
|
+
let(:provenance_fact_1) do
|
10
|
+
Factories::ProvenanceFact.context(subject)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:provenance_fact_2) do
|
14
|
+
Factories::ProvenanceFact.created_by(subject)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#new" do
|
18
|
+
it "has a unique id (new_id.class)" do
|
19
|
+
provenance_fact_1.id.should be_a(id_class)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "two provenance_facts have different id" do
|
23
|
+
provenance_fact_1.id.should_not == provenance_fact_2.id
|
24
|
+
end
|
25
|
+
|
26
|
+
it "has nil provenance_subject" do
|
27
|
+
provenance_fact_1.provenance_subject.should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has correct subject" do
|
31
|
+
provenance_fact_1.subject.should == subject
|
32
|
+
end
|
33
|
+
|
34
|
+
it "has correct predicate" do
|
35
|
+
provenance_fact_1.predicate.should == "https://data.vandenabeele.com/ontologies/provenance#context"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "has correct object" do
|
39
|
+
provenance_fact_1.object.should == "public"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "raises an ProvenanceError when provenance_subject is present in options hash" do
|
43
|
+
lambda { described_class.new(
|
44
|
+
provenance_subject: described_class.new_subject,
|
45
|
+
predicate: "test",
|
46
|
+
object: "test") } .
|
47
|
+
should raise_error ProvenanceError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "valid?" do
|
52
|
+
it "the factory isi valid?" do
|
53
|
+
provenance_fact_1.should be_valid
|
54
|
+
end
|
55
|
+
|
56
|
+
it "with ! provenance_subject is not valid?" do
|
57
|
+
provenance_fact_1.stub(:provenance_subject).and_return(subject)
|
58
|
+
provenance_fact_1.should_not be_valid
|
59
|
+
end
|
60
|
+
|
61
|
+
it "without subject is not valid?" do
|
62
|
+
provenance_fact_1.stub(:subject).and_return(nil)
|
63
|
+
provenance_fact_1.should_not be_valid
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#dup_with_subject" do
|
68
|
+
|
69
|
+
let (:new_fact) do
|
70
|
+
provenance_fact_1.dup_with_subject(subject)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "is a different instance" do
|
74
|
+
new_fact.should_not be_equal(provenance_fact_1)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "is from the same class" do
|
78
|
+
new_fact.should be_a(provenance_fact_1.class)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "update_used_provenance_subjects" do
|
83
|
+
it "does nothing for a provenance_fact" do
|
84
|
+
h = {}
|
85
|
+
provenance_fact_1.update_used_provenance_subjects(h)
|
86
|
+
h.should be_empty
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "Factories do not fail" do
|
91
|
+
it "Factories::ProvenanceFact.context is OK" do
|
92
|
+
Factories::ProvenanceFact.context.should_not be_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it "Factories::ProvenanceFact.created_by is OK" do
|
96
|
+
Factories::ProvenanceFact.created_by.should_not be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "Factories::ProvenanceFact.original_source is OK" do
|
100
|
+
Factories::ProvenanceFact.original_source.should_not be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
it "Factories::ProvenanceFact.new_subject is OK" do
|
104
|
+
Factories::ProvenanceFact.new_subject.should be_a(ProvenanceFact.new_subject.class)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dbd
|
4
|
+
describe ProvenanceResource do
|
5
|
+
|
6
|
+
let(:provenance_resource) { described_class.new }
|
7
|
+
let(:provenance_resource_subject) { provenance_resource.subject }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
describe "without a subject argument" do
|
11
|
+
it "has created a new subject" do
|
12
|
+
provenance_resource.subject.should be_a(described_class.new_subject.class)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with a subject argument" do
|
17
|
+
it "has stored the resource_subject" do
|
18
|
+
described_class.new(subject: provenance_resource_subject).subject.should == provenance_resource_subject
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "with a provenance_subject argument" do
|
23
|
+
it "raises an ProvenanceError" do
|
24
|
+
lambda { described_class.new(provenance_subject: provenance_resource_subject) } .
|
25
|
+
should raise_error ProvenanceError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "provenance_subject" do
|
31
|
+
it "raises NoMethodError when called" do
|
32
|
+
lambda { provenance_resource.provenance_subject } . should raise_error NoMethodError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "Factories::Resource" do
|
37
|
+
it ".provenance_resource works" do
|
38
|
+
Factories::ProvenanceResource.provenance_resource
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "the collection" do
|
43
|
+
|
44
|
+
let(:provenance_fact_context) { Factories::ProvenanceFact.context }
|
45
|
+
let(:provenance_fact_context_with_incorrect_subject) { Factories::ProvenanceFact.context(Factories::ProvenanceFact.new_subject) }
|
46
|
+
let(:provenance_fact_context_with_correct_subject) { Factories::ProvenanceFact.context(provenance_resource_subject) }
|
47
|
+
let(:fact_1) { Factories::Fact.fact_1(provenance_resource_subject) }
|
48
|
+
|
49
|
+
describe "data facts" do
|
50
|
+
it "with correct subject" do
|
51
|
+
provenance_resource << provenance_fact_context_with_correct_subject
|
52
|
+
provenance_resource.first.subject.should == provenance_resource_subject
|
53
|
+
end
|
54
|
+
|
55
|
+
it "with incorrect subject it raise SubjectError" do
|
56
|
+
lambda { provenance_resource << provenance_fact_context_with_incorrect_subject } .
|
57
|
+
should raise_error SubjectError
|
58
|
+
end
|
59
|
+
|
60
|
+
it "with nil subject" do
|
61
|
+
provenance_resource << provenance_fact_context
|
62
|
+
provenance_resource.first.subject.should == provenance_resource_subject
|
63
|
+
end
|
64
|
+
|
65
|
+
it "with nil (=correct) provenance_subject" do
|
66
|
+
provenance_resource << provenance_fact_context
|
67
|
+
provenance_resource.first.provenance_subject.should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "with incorrect provenance_subjecti ProvenanceError" do
|
71
|
+
lambda { provenance_resource << fact_1 } .
|
72
|
+
should raise_error ProvenanceError
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|