dbd 0.0.1
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/.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
|