dbd 0.0.7 → 0.0.8
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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/HISTORY.txt +6 -0
- data/bin/test_1.rb +34 -0
- data/dbd.gemspec +4 -4
- data/lib/dbd/fact.rb +60 -20
- data/lib/dbd/fact/id.rb +5 -9
- data/lib/dbd/fact/subject.rb +5 -9
- data/lib/dbd/graph.rb +1 -1
- data/lib/dbd/time_stamp.rb +36 -18
- data/lib/dbd/version.rb +1 -1
- data/spec/factories/fact.rb +9 -0
- data/spec/factories/fact/id.rb +1 -6
- data/spec/factories/fact/subject.rb +2 -7
- data/spec/factories/resource.rb +5 -0
- data/spec/factories/time_stamp.rb +5 -1
- data/spec/lib/dbd/fact/collection/collection_spec.rb +2 -2
- data/spec/lib/dbd/fact/id/factory_spec.rb +1 -5
- data/spec/lib/dbd/fact/id/id_spec.rb +4 -16
- data/spec/lib/dbd/fact/methods_spec.rb +56 -11
- data/spec/lib/dbd/fact/new_spec.rb +25 -7
- data/spec/lib/dbd/fact/subject/factory_spec.rb +4 -12
- data/spec/lib/dbd/fact/subject/subject_spec.rb +4 -16
- data/spec/lib/dbd/graph/add_to_graph_spec.rb +1 -1
- data/spec/lib/dbd/graph/from_csv_spec.rb +18 -1
- data/spec/lib/dbd/performance_spec.rb +1 -0
- data/spec/lib/dbd/resource/factory_spec.rb +4 -0
- data/spec/lib/dbd/time_stamp/comparisons_spec.rb +25 -3
- data/spec/lib/dbd/time_stamp/factory_spec.rb +2 -1
- data/spec/lib/dbd/time_stamp/methods_spec.rb +4 -4
- data/spec/lib/dbd/time_stamp/new_spec.rb +8 -1
- metadata +19 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ceec5332dfdb3174ee303dcd09cf401186990c8
|
4
|
+
data.tar.gz: a7e61a7b4acc1dcb9a966369ba1c4d8a853b5f9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1da941433fd3f5dc0f077992bec69d6dc2a3dc761d52549934dd707e713d6317495ae54659e764c21bab079789ed3e74e260ff639bf237715f14222bc267e9b
|
7
|
+
data.tar.gz: cfdd88e0c3ed9e012f354008ab32685c052fffef7897492d78663d2d243c76abd9ae0a3f3a0c2b8b4f5c54ab8371553a9f129436a36a25ea57e46b86d555d8ef
|
data/.travis.yml
CHANGED
data/HISTORY.txt
CHANGED
data/bin/test_1.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This is a very primitive implementation:
|
4
|
+
# the CSV is first fully built and only then
|
5
|
+
# written to disk. Needs to be modified to
|
6
|
+
# stream to disk.
|
7
|
+
|
8
|
+
count = ARGV[0].to_i
|
9
|
+
unless count > 0
|
10
|
+
puts "Give a 'count' as first argument."
|
11
|
+
exit(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
filename = ARGV[1]
|
15
|
+
unless filename.size > 0
|
16
|
+
puts "Give a 'filename' as second argument."
|
17
|
+
exit(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'dbd'
|
21
|
+
provenance_resource = Dbd::ProvenanceResource.new
|
22
|
+
provenance_resource << Dbd::ProvenanceFact.new(predicate: "prov:test" , object: "A" * 10)
|
23
|
+
|
24
|
+
resource = Dbd::Resource.new(provenance_subject: provenance_resource.subject)
|
25
|
+
(0...count).each do |i|
|
26
|
+
resource << Dbd::Fact.new(predicate: "test", object: "#{'B' * 80} #{i}")
|
27
|
+
end
|
28
|
+
|
29
|
+
graph = Dbd::Graph.new
|
30
|
+
graph << provenance_resource << resource
|
31
|
+
|
32
|
+
File.open(filename, 'w') do |f|
|
33
|
+
f << graph.to_CSV
|
34
|
+
end
|
data/dbd.gemspec
CHANGED
@@ -18,13 +18,13 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency 'bundler'
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'guard-rspec'
|
24
|
-
spec.add_development_dependency 'rb-fsevent'
|
24
|
+
spec.add_development_dependency 'rb-fsevent'
|
25
25
|
spec.add_development_dependency 'terminal-notifier-guard'
|
26
26
|
spec.add_development_dependency 'yard'
|
27
27
|
spec.add_runtime_dependency 'neography'
|
28
|
-
spec.add_runtime_dependency 'rdf'
|
29
|
-
spec.add_runtime_dependency 'ruby_peter_v', '>= 0.0.
|
28
|
+
spec.add_runtime_dependency 'rdf'
|
29
|
+
spec.add_runtime_dependency 'ruby_peter_v', '>= 0.0.9'
|
30
30
|
end
|
data/lib/dbd/fact.rb
CHANGED
@@ -78,41 +78,43 @@ module Dbd
|
|
78
78
|
# This implements a "form" of immutable behavior. The value can
|
79
79
|
# be set once (possibly after creation the object), but can
|
80
80
|
# never be changed after that.
|
81
|
+
#
|
82
|
+
# The input class is validated (easy confusion with String or Time).
|
81
83
|
def time_stamp=(time_stamp)
|
82
|
-
|
84
|
+
validate_time_stamp_class(time_stamp)
|
83
85
|
set_once(:time_stamp, time_stamp)
|
84
86
|
end
|
85
87
|
|
86
88
|
##
|
87
|
-
# A set_once setter for
|
89
|
+
# A set_once setter for provenance_subject.
|
88
90
|
#
|
89
91
|
# This implements a "form" of immutable behavior. The value can
|
90
92
|
# be set once (possibly after creation the object), but can
|
91
93
|
# never be changed after that.
|
92
|
-
def
|
93
|
-
set_once(:
|
94
|
+
def provenance_subject=(provenance_subject)
|
95
|
+
set_once(:provenance_subject, provenance_subject)
|
94
96
|
end
|
95
97
|
|
96
98
|
##
|
97
|
-
# A set_once setter for
|
99
|
+
# A set_once setter for subject.
|
98
100
|
#
|
99
101
|
# This implements a "form" of immutable behavior. The value can
|
100
102
|
# be set once (possibly after creation the object), but can
|
101
103
|
# never be changed after that.
|
102
|
-
def
|
103
|
-
set_once(:
|
104
|
+
def subject=(subject)
|
105
|
+
set_once(:subject, subject)
|
104
106
|
end
|
105
107
|
|
106
108
|
##
|
107
|
-
# @return [
|
109
|
+
# @return [String] A new subject string.
|
108
110
|
def self.new_subject
|
109
|
-
Subject.
|
111
|
+
Subject.new_subject
|
110
112
|
end
|
111
113
|
|
112
114
|
##
|
113
|
-
# @return [
|
115
|
+
# @return [String] A new id string.
|
114
116
|
def self.new_id
|
115
|
-
ID.
|
117
|
+
ID.new_id
|
116
118
|
end
|
117
119
|
|
118
120
|
##
|
@@ -121,13 +123,14 @@ module Dbd
|
|
121
123
|
# @param [Hash{Symbol => Object}] options
|
122
124
|
# @option options [#to_s] :predicate Required : the predicate for this Fact
|
123
125
|
# @option options [#to_s] :object Required : the object for this Fact (required)
|
124
|
-
# @option options [
|
125
|
-
# @option options [
|
126
|
+
# @option options [String (uuid)] :provenance_subject (nil) Optional: the subject of the provenance(resource|fact)
|
127
|
+
# @option options [String (uuid)] :subject (nil) Optional: the subject for this Fact
|
126
128
|
# @option options [TimeStamp] :time_stamp (nil) Optional: the time_stamp for this Fact
|
127
|
-
# @option options [
|
129
|
+
# @option options [String (uuid)] :id Optional : set the id
|
128
130
|
def initialize(options)
|
129
131
|
@id = options[:id] || self.class.new_id
|
130
132
|
@time_stamp = options[:time_stamp]
|
133
|
+
validate_time_stamp_class(@time_stamp)
|
131
134
|
@provenance_subject = options[:provenance_subject]
|
132
135
|
@subject = options[:subject]
|
133
136
|
@predicate = options[:predicate]
|
@@ -143,14 +146,38 @@ module Dbd
|
|
143
146
|
end
|
144
147
|
|
145
148
|
##
|
146
|
-
#
|
149
|
+
# @return [Array] The 6 values of a Fact converted to a string.
|
150
|
+
# This is similar to the 6 entries in the to_CSV mapping
|
151
|
+
def string_values
|
152
|
+
values.map(&:to_s)
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# Constructs a Fact or ProvenanceFact from a string values array
|
147
157
|
# (e.g. pulled from a CSV row).
|
148
158
|
#
|
149
159
|
# @param [Array] values Required : the array with values, organized as in attributes
|
150
160
|
# @return [Fact, ProvenanceFact] the constructed fact
|
151
|
-
def self.
|
152
|
-
|
153
|
-
fact_from_hash(
|
161
|
+
def self.from_string_values(string_values)
|
162
|
+
string_hash = hash_from_values(string_values)
|
163
|
+
fact_from_hash(values_hash(string_hash))
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Equivalent facts (have all same values, except time_stamp).
|
168
|
+
#
|
169
|
+
# For "equality" only a test on the id is used. If the id
|
170
|
+
# (which is a uuid) is the same, we assume that is the "same"
|
171
|
+
# fact. This equivalent? method is used to test is equal
|
172
|
+
# methods are "really" equivalent.
|
173
|
+
#
|
174
|
+
# The time_stamp may be slightly different (because shifts
|
175
|
+
# of a few nanoseconds will be required to resolve collisions
|
176
|
+
# on merge).
|
177
|
+
def equivalent?(other)
|
178
|
+
(self.class.attributes - [:time_stamp]).
|
179
|
+
all?{ |attribute| self.send(attribute) == other.send(attribute) } &&
|
180
|
+
self.time_stamp.near?(other.time_stamp)
|
154
181
|
end
|
155
182
|
|
156
183
|
##
|
@@ -219,19 +246,32 @@ module Dbd
|
|
219
246
|
"#{provenance_subject.to_s[0...8]}"
|
220
247
|
end
|
221
248
|
|
249
|
+
# FIXME This has to move to a Fact::Factory
|
222
250
|
def self.hash_from_values(values)
|
223
251
|
# Do not keep "empty" values (e.g. the provenance_subject for a ProvenanceFact).
|
224
|
-
attributes_values_array = [attributes, values].transpose.
|
252
|
+
attributes_values_array = [attributes, values].transpose.delete_if{|a,v| v.nil? || v == ''}
|
225
253
|
Hash[attributes_values_array]
|
226
254
|
end
|
227
255
|
|
256
|
+
def self.values_hash(string_hash)
|
257
|
+
string_hash.dup.tap do |h|
|
258
|
+
h[:time_stamp] = TimeStamp.new(time: h[:time_stamp])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
228
262
|
def self.fact_from_hash(hash)
|
229
263
|
if hash[:provenance_subject]
|
230
|
-
new(hash)
|
264
|
+
Fact.new(hash)
|
231
265
|
else
|
232
266
|
ProvenanceFact.new(hash)
|
233
267
|
end
|
234
268
|
end
|
235
269
|
|
270
|
+
def validate_time_stamp_class(time_stamp)
|
271
|
+
unless time_stamp.nil? || time_stamp.is_a?(TimeStamp)
|
272
|
+
raise ArgumentError, "time_stamp is of class #{time_stamp.class}, should be TimeStamp"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
236
276
|
end
|
237
277
|
end
|
data/lib/dbd/fact/id.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
1
|
module Dbd
|
2
2
|
class Fact
|
3
|
-
|
4
|
-
|
5
|
-
def initialize(options = {})
|
6
|
-
@uuid = options[:uuid] || Helpers::UUID.new.to_s
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_s
|
10
|
-
@uuid
|
11
|
-
end
|
3
|
+
module ID
|
12
4
|
|
13
5
|
def self.regexp
|
14
6
|
Helpers::UUID.regexp
|
15
7
|
end
|
16
8
|
|
9
|
+
def self.new_id
|
10
|
+
Helpers::UUID.new.to_s
|
11
|
+
end
|
12
|
+
|
17
13
|
end
|
18
14
|
end
|
19
15
|
end
|
data/lib/dbd/fact/subject.rb
CHANGED
@@ -2,20 +2,16 @@ require 'dbd/helpers/uuid'
|
|
2
2
|
|
3
3
|
module Dbd
|
4
4
|
class Fact
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
@uuid = options[:uuid] || Helpers::UUID.new.to_s
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_s
|
12
|
-
@uuid
|
13
|
-
end
|
5
|
+
module Subject
|
14
6
|
|
15
7
|
def self.regexp
|
16
8
|
Helpers::UUID.regexp
|
17
9
|
end
|
18
10
|
|
11
|
+
def self.new_subject
|
12
|
+
Helpers::UUID.new.to_s
|
13
|
+
end
|
14
|
+
|
19
15
|
end
|
20
16
|
end
|
21
17
|
end
|
data/lib/dbd/graph.rb
CHANGED
data/lib/dbd/time_stamp.rb
CHANGED
@@ -42,10 +42,11 @@ module Dbd
|
|
42
42
|
# Builds a new TimeStamp.
|
43
43
|
#
|
44
44
|
# @param [Hash{Symbol => Object}] options
|
45
|
-
# @option options [Time] :time (Time.now) force the time to this value
|
45
|
+
# @option options [Time, String] :time (Time.now) force the time to this value
|
46
46
|
# @option options [TimeStamp] :larger_than (void) time_stamp must be larger than this
|
47
47
|
def initialize(options={})
|
48
48
|
@time = options[:time] || new_time(options[:larger_than])
|
49
|
+
@time = time_from_s(@time) if @time.is_a?(String)
|
49
50
|
end
|
50
51
|
|
51
52
|
##
|
@@ -66,34 +67,51 @@ module Dbd
|
|
66
67
|
Rational("#{1+rand(999)}/1_000_000_000")
|
67
68
|
end
|
68
69
|
|
69
|
-
def
|
70
|
+
def time_format
|
70
71
|
'%F %T.%N %Z'
|
71
72
|
end
|
72
73
|
|
74
|
+
##
|
75
|
+
# with a nanosecond granularity and in UTC
|
76
|
+
def time_from_s(time_string)
|
77
|
+
# For ns precision in JRuby this extended process is required
|
78
|
+
time_hash = DateTime._strptime(time_string, time_format)
|
79
|
+
validate_time_zone(time_hash)
|
80
|
+
Time.utc(time_hash[:year],
|
81
|
+
time_hash[:mon],
|
82
|
+
time_hash[:mday],
|
83
|
+
time_hash[:hour],
|
84
|
+
time_hash[:min],
|
85
|
+
time_hash[:sec],
|
86
|
+
time_hash[:sec_fraction] * 1_000_000)
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_time_zone(time_hash)
|
90
|
+
unless time_hash[:zone] == 'UTC'
|
91
|
+
raise(ArgumentError, "Time zone was #{time_hash[:zone]}, must be 'UTC'")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
73
95
|
public
|
74
96
|
|
75
97
|
##
|
76
98
|
# with a nanosecond granularity and in UTC
|
77
99
|
def to_s
|
78
|
-
@time.strftime(
|
100
|
+
@time.strftime(time_format)
|
79
101
|
end
|
80
102
|
|
103
|
+
# Max drift in time_stamp
|
104
|
+
MAX_DRIFT = Rational("1/1_000_000")
|
105
|
+
|
81
106
|
##
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
time_hash[:mon],
|
91
|
-
time_hash[:mday],
|
92
|
-
time_hash[:hour],
|
93
|
-
time_hash[:min],
|
94
|
-
time_hash[:sec],
|
95
|
-
time_hash[:sec_fraction] * 1_000_000)
|
96
|
-
TimeStamp.new(time: time)
|
107
|
+
# determines if 2 time_stamps are "near".
|
108
|
+
#
|
109
|
+
# The time_stamp of an equivalent fact may be slightly different
|
110
|
+
# (because shifts of a few nanoseconds will be required to resolve
|
111
|
+
# collisions on a merge of fact streams with overlapping time_stamp
|
112
|
+
# ranges).
|
113
|
+
def near?(other)
|
114
|
+
(self - other).abs <= MAX_DRIFT
|
97
115
|
end
|
98
116
|
|
99
117
|
def >(other)
|
data/lib/dbd/version.rb
CHANGED
data/spec/factories/fact.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding=utf-8
|
1
2
|
module Factories
|
2
3
|
module Fact
|
3
4
|
|
@@ -23,6 +24,14 @@ module Factories
|
|
23
24
|
object: "Gandhi")
|
24
25
|
end
|
25
26
|
|
27
|
+
def self.fact_with_special_chars(provenance_subject = nil, subject = nil)
|
28
|
+
factory_for.new(
|
29
|
+
provenance_subject: provenance_subject,
|
30
|
+
subject: subject,
|
31
|
+
predicate: "http://example.org/test/comment",
|
32
|
+
object: "A long story\nreally with a comma, a double quote \" and a non-ASCII char éà Über.")
|
33
|
+
end
|
34
|
+
|
26
35
|
def self.fact_with_time_stamp(time_stamp)
|
27
36
|
factory_for.new(
|
28
37
|
time_stamp: time_stamp,
|
data/spec/factories/fact/id.rb
CHANGED
@@ -1,17 +1,12 @@
|
|
1
1
|
module Factories
|
2
2
|
module Fact
|
3
3
|
module Subject
|
4
|
-
|
5
|
-
def self.factory_for
|
6
|
-
::Dbd::Fact::Subject
|
7
|
-
end
|
8
|
-
|
9
4
|
def self.fixed_subject
|
10
|
-
|
5
|
+
"2e9fbc87-2e94-47e9-a8fd-121cc4bc3e8f"
|
11
6
|
end
|
12
7
|
|
13
8
|
def self.fixed_provenance_subject
|
14
|
-
|
9
|
+
"40fab407-9b04-4a51-9a52-d978abfcbb1f"
|
15
10
|
end
|
16
11
|
end
|
17
12
|
end
|
data/spec/factories/resource.rb
CHANGED
@@ -5,6 +5,11 @@ module Factories
|
|
5
5
|
::Dbd::Resource
|
6
6
|
end
|
7
7
|
|
8
|
+
def self.empty(provenance_subject)
|
9
|
+
subject = Fact.new_subject
|
10
|
+
factory_for.new(subject: subject, provenance_subject: provenance_subject)
|
11
|
+
end
|
12
|
+
|
8
13
|
def self.facts_resource(provenance_subject)
|
9
14
|
subject = Fact.new_subject
|
10
15
|
factory_for.new(subject: subject, provenance_subject: provenance_subject).tap do |resource|
|
@@ -5,8 +5,12 @@ module Factories
|
|
5
5
|
::Dbd::TimeStamp
|
6
6
|
end
|
7
7
|
|
8
|
+
def self.fixed_time_string
|
9
|
+
"2013-06-17 21:55:09.967653013 UTC"
|
10
|
+
end
|
11
|
+
|
8
12
|
def self.fixed_time_stamp
|
9
|
-
factory_for.
|
13
|
+
factory_for.new(time: fixed_time_string)
|
10
14
|
end
|
11
15
|
end
|
12
16
|
end
|
@@ -98,8 +98,8 @@ module Dbd
|
|
98
98
|
|
99
99
|
describe "validate that only 'newer' elements are added" do
|
100
100
|
before(:each) do
|
101
|
-
fact_2_with_subject.stub(:time_stamp).and_return(TimeStamp.new(time: Time.
|
102
|
-
fact_3_with_subject.stub(:time_stamp).and_return(TimeStamp.new(time: Time.
|
101
|
+
fact_2_with_subject.stub(:time_stamp).and_return(TimeStamp.new(time: Time.utc(2013,05,9,12,0,0)))
|
102
|
+
fact_3_with_subject.stub(:time_stamp).and_return(TimeStamp.new(time: Time.utc(2013,05,9,12,0,1)))
|
103
103
|
end
|
104
104
|
|
105
105
|
it "adding an element with a newer time_stamp succeeds" do
|
@@ -7,12 +7,8 @@ module Dbd
|
|
7
7
|
|
8
8
|
let(:fixed_id) { Factories::Fact::ID.fixed_id }
|
9
9
|
|
10
|
-
it "fixed_id is an Fact::ID" do
|
11
|
-
fixed_id.should be_a(described_class)
|
12
|
-
end
|
13
|
-
|
14
10
|
it "fixed_id is exactly this fixed id" do
|
15
|
-
fixed_id.
|
11
|
+
fixed_id.should == "825e44d5-af33-4858-8047-549bd813daa8"
|
16
12
|
end
|
17
13
|
end
|
18
14
|
end
|
@@ -3,25 +3,13 @@ require 'spec_helper'
|
|
3
3
|
module Dbd
|
4
4
|
class Fact
|
5
5
|
describe ID do
|
6
|
-
describe ".new" do
|
7
|
-
it "creates an ID with a random uuid" do
|
8
|
-
subject.should be_a(described_class)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "optionally takes an options hash with :uuid key" do
|
12
|
-
uuid = "825e44d5-af33-4858-8047-549bd813daa8"
|
13
|
-
id = described_class.new(uuid: uuid)
|
14
|
-
id.to_s.should == uuid
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it "#to_s is a UUID string" do
|
19
|
-
subject.to_s.should match(Helpers::UUID.regexp)
|
20
|
-
end
|
21
|
-
|
22
6
|
it ".regexp has a regexp for the to_s" do
|
23
7
|
described_class.regexp.should == Helpers::UUID.regexp
|
24
8
|
end
|
9
|
+
|
10
|
+
it ".new_id" do
|
11
|
+
described_class.new_id.should match(described_class.regexp)
|
12
|
+
end
|
25
13
|
end
|
26
14
|
end
|
27
15
|
end
|
@@ -8,6 +8,7 @@ module Dbd
|
|
8
8
|
let(:fact_1) { Factories::Fact.fact_1(provenance_subject) }
|
9
9
|
let(:fact_2_with_subject) { Factories::Fact.fact_2_with_subject(provenance_subject) }
|
10
10
|
let(:fact_with_newline) { Factories::Fact.fact_with_newline(provenance_subject) }
|
11
|
+
let(:full_fact) { Factories::Fact.full_fact }
|
11
12
|
|
12
13
|
describe "time_stamp=" do
|
13
14
|
it "checks the type (too easy to try to give a Time arg)" do
|
@@ -78,7 +79,7 @@ module Dbd
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
describe "attributes
|
82
|
+
describe "attributes" do
|
82
83
|
it "there are 6 attributes" do
|
83
84
|
described_class.attributes.size.should == 6
|
84
85
|
end
|
@@ -86,31 +87,75 @@ module Dbd
|
|
86
87
|
it "first attribute is :id" do
|
87
88
|
described_class.attributes.first.should == :id
|
88
89
|
end
|
90
|
+
end
|
89
91
|
|
92
|
+
describe "values" do
|
90
93
|
it "there are 6 values" do
|
91
|
-
|
94
|
+
full_fact.values.size.should == 6
|
95
|
+
end
|
96
|
+
|
97
|
+
it "the second element (time_stamp) is a TimeStamp" do
|
98
|
+
full_fact.values[1].should be_a(TimeStamp)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "string_values" do
|
103
|
+
it "there are 6 string_values" do
|
104
|
+
full_fact.string_values.size.should == 6
|
105
|
+
end
|
106
|
+
|
107
|
+
it "the second element (time_stamp) is a String" do
|
108
|
+
full_fact.string_values[1].should be_a(String)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "provenance_fact?" do
|
113
|
+
it "is false for a base fact or derived from it that is not a ProvenanceFact " do
|
114
|
+
fact_1.provenance_fact?.should be_false
|
92
115
|
end
|
93
116
|
end
|
94
117
|
|
95
|
-
def
|
118
|
+
def string_values
|
96
119
|
["825e44d5-af33-4858-8047-549bd813daa8",
|
97
|
-
"2013-06-17 21:55:09.
|
120
|
+
"2013-06-17 21:55:09.967653013 UTC",
|
98
121
|
"40fab407-9b04-4a51-9a52-d978abfcbb1f",
|
99
122
|
"2e9fbc87-2e94-47e9-a8fd-121cc4bc3e8f",
|
100
123
|
"http://example.org/test/name",
|
101
124
|
"Gandhi"]
|
102
125
|
end
|
103
126
|
|
104
|
-
describe "
|
105
|
-
it "reads the values correctly" do
|
106
|
-
fact = described_class.
|
107
|
-
fact.
|
127
|
+
describe "from_string_values" do
|
128
|
+
it "reads the values correctly (round trip test)" do
|
129
|
+
fact = described_class.from_string_values(string_values)
|
130
|
+
fact.string_values.should == string_values
|
108
131
|
end
|
109
132
|
end
|
110
133
|
|
111
|
-
describe "
|
112
|
-
|
113
|
-
|
134
|
+
describe "equivalent?" do
|
135
|
+
|
136
|
+
let(:ref) { described_class.from_string_values(string_values) }
|
137
|
+
|
138
|
+
it "is true for facts with same values" do
|
139
|
+
other = described_class.from_string_values(string_values)
|
140
|
+
other.should be_equivalent(ref)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "is false for each of the entries largely different" do
|
144
|
+
(0...string_values.size).each do |index|
|
145
|
+
string_values_1_modified = string_values.dup.tap { |_string_values|
|
146
|
+
_string_values[index][3] = '4' # different and valid for all cases
|
147
|
+
}
|
148
|
+
other = described_class.from_string_values(string_values_1_modified)
|
149
|
+
other.should_not be_equivalent(ref)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it "is true when the time_stamp is 500 ns larger" do
|
154
|
+
string_values_time_modified = string_values.dup.tap { |_string_values|
|
155
|
+
_string_values[1] = "2013-06-17 21:55:09.967653513 UTC"
|
156
|
+
}
|
157
|
+
other = described_class.from_string_values(string_values_time_modified)
|
158
|
+
other.should be_equivalent(ref)
|
114
159
|
end
|
115
160
|
end
|
116
161
|
end
|
@@ -2,21 +2,23 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Dbd
|
4
4
|
describe Fact do
|
5
|
+
let(:provenance_subject) { ProvenanceFact.new_subject }
|
5
6
|
let(:fact_1) { Factories::Fact.fact_1(provenance_subject) }
|
6
7
|
let(:fact_2_with_subject) { Factories::Fact.fact_2_with_subject(provenance_subject) }
|
7
|
-
let(:provenance_subject) { ProvenanceFact.new_subject }
|
8
8
|
let(:data_predicate) { "http://example.org/test/name" }
|
9
9
|
let(:string_object_1) { "Gandhi" }
|
10
|
-
let(:
|
11
|
-
let(:
|
10
|
+
let(:id_regexp) { Fact::ID.regexp }
|
11
|
+
let(:subject_regexp) { Fact::Subject.regexp }
|
12
12
|
let(:forced_id) { described_class.new_id }
|
13
|
+
let(:subject) { described_class.new_subject }
|
13
14
|
let(:fact_with_forced_id) { Factories::Fact.fact_with_forced_id(forced_id) }
|
14
15
|
let(:time_stamp) { TimeStamp.new }
|
15
16
|
let(:fact_with_time_stamp) { Factories::Fact.fact_with_time_stamp(time_stamp) }
|
17
|
+
let(:fact_with_incorrect_time_stamp) { Factories::Fact.fact_with_time_stamp(time_stamp.time) }
|
16
18
|
|
17
19
|
describe ".new_subject" do
|
18
20
|
it "creates a new (random) subject" do
|
19
|
-
described_class.new_subject.should
|
21
|
+
described_class.new_subject.should match(subject_regexp)
|
20
22
|
end
|
21
23
|
|
22
24
|
it "creating a second one is different" do
|
@@ -26,9 +28,21 @@ module Dbd
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
31
|
+
describe ".new_id" do
|
32
|
+
it "creates a new (random) id" do
|
33
|
+
described_class.new_id.should match(id_regexp)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "creating a second one is different" do
|
37
|
+
id_1 = described_class.new_id
|
38
|
+
id_2 = described_class.new_id
|
39
|
+
id_1.should_not == id_2
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
29
43
|
describe "create a fact" do
|
30
|
-
it "has a unique id (
|
31
|
-
fact_1.id.should
|
44
|
+
it "has a unique id (matches id_regexp)" do
|
45
|
+
fact_1.id.should match(id_regexp)
|
32
46
|
end
|
33
47
|
|
34
48
|
it "two facts have different id" do
|
@@ -43,12 +57,16 @@ module Dbd
|
|
43
57
|
fact_with_time_stamp.time_stamp.should == time_stamp
|
44
58
|
end
|
45
59
|
|
60
|
+
it "setting the time_stamp to a non TimeStamp raises ArgumentError" do
|
61
|
+
lambda{ fact_with_incorrect_time_stamp }.should raise_error ArgumentError
|
62
|
+
end
|
63
|
+
|
46
64
|
it "new sets the provenance_subject" do
|
47
65
|
fact_1.provenance_subject.should == provenance_subject
|
48
66
|
end
|
49
67
|
|
50
68
|
it "new sets the subject" do
|
51
|
-
fact_2_with_subject.subject.should
|
69
|
+
fact_2_with_subject.subject.should match(subject_regexp)
|
52
70
|
end
|
53
71
|
|
54
72
|
it "a nil predicate raises PredicateError" do
|
@@ -9,22 +9,14 @@ module Dbd
|
|
9
9
|
let(:fixed_provenance_subject) { Factories::Fact::Subject.fixed_provenance_subject }
|
10
10
|
|
11
11
|
describe "fixed_subject" do
|
12
|
-
it "is
|
13
|
-
fixed_subject.should
|
14
|
-
end
|
15
|
-
|
16
|
-
it "fixed_subject is exactly this fixed id" do
|
17
|
-
fixed_subject.to_s.should == "2e9fbc87-2e94-47e9-a8fd-121cc4bc3e8f"
|
12
|
+
it "fixed_subject is exactly this fixed subject" do
|
13
|
+
fixed_subject.should == "2e9fbc87-2e94-47e9-a8fd-121cc4bc3e8f"
|
18
14
|
end
|
19
15
|
end
|
20
16
|
|
21
17
|
describe "fixed_provenance_subject" do
|
22
|
-
it "is
|
23
|
-
fixed_provenance_subject.should
|
24
|
-
end
|
25
|
-
|
26
|
-
it "fixed_provenance_subject is exactly this fixed id" do
|
27
|
-
fixed_provenance_subject.to_s.should == "40fab407-9b04-4a51-9a52-d978abfcbb1f"
|
18
|
+
it "fixed_provenance_subject is exactly this fixed subject" do
|
19
|
+
fixed_provenance_subject.should == "40fab407-9b04-4a51-9a52-d978abfcbb1f"
|
28
20
|
end
|
29
21
|
end
|
30
22
|
end
|
@@ -3,25 +3,13 @@ require 'spec_helper'
|
|
3
3
|
module Dbd
|
4
4
|
class Fact
|
5
5
|
describe Subject do
|
6
|
-
describe ".new" do
|
7
|
-
it "creates a Subject" do
|
8
|
-
subject.should be_a(described_class)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "takes an optional :uuid option argument" do
|
12
|
-
uuid = "fe75eae3-cb14-4495-b726-7ecba8798b6d"
|
13
|
-
subject = described_class.new(uuid: uuid)
|
14
|
-
subject.to_s.should == uuid
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
it "#to_s is a UUID string" do
|
19
|
-
subject.to_s.should match(Helpers::UUID.regexp)
|
20
|
-
end
|
21
|
-
|
22
6
|
it ".regexp has a regexp for the to_s" do
|
23
7
|
described_class.regexp.should == Helpers::UUID.regexp
|
24
8
|
end
|
9
|
+
|
10
|
+
it ".new_subject" do
|
11
|
+
described_class.new_subject.should match(described_class.regexp)
|
12
|
+
end
|
25
13
|
end
|
26
14
|
end
|
27
15
|
end
|
@@ -54,7 +54,7 @@ module Dbd
|
|
54
54
|
|
55
55
|
# NOTE: reduced the far_future from 2500 to 2250 as work around for
|
56
56
|
# http://jira.codehaus.org/browse/JRUBY-7095
|
57
|
-
let(:far_future) { TimeStamp.new(time: Time.
|
57
|
+
let(:far_future) { TimeStamp.new(time: Time.utc(2250,1,1,12,0,0)) }
|
58
58
|
|
59
59
|
it "don't touch the time_stamp if already set" do
|
60
60
|
data_fact.time_stamp = far_future
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding=utf-8
|
1
2
|
require 'spec_helper'
|
2
3
|
|
3
4
|
module Dbd
|
@@ -14,7 +15,7 @@ module Dbd
|
|
14
15
|
graph_from_CSV.to_CSV.should == graph.to_CSV
|
15
16
|
end
|
16
17
|
|
17
|
-
describe "
|
18
|
+
describe ".from_CSV reads back a csv exported graph correctly" do
|
18
19
|
|
19
20
|
describe "for a graph with only provenance_facts" do
|
20
21
|
|
@@ -45,5 +46,21 @@ module Dbd
|
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
49
|
+
|
50
|
+
describe ".from_CSV reads special cases correctly" do
|
51
|
+
|
52
|
+
let(:provenance_subject) { Factories::Fact::Subject.fixed_provenance_subject }
|
53
|
+
let(:resource) { Factories::Resource.empty(provenance_subject) }
|
54
|
+
let(:special_fact) { Factories::Fact.fact_with_special_chars(provenance_subject, resource.subject) }
|
55
|
+
|
56
|
+
it "as object" do
|
57
|
+
resource << special_fact
|
58
|
+
graph = described_class.new << resource
|
59
|
+
csv = graph.to_CSV
|
60
|
+
csv.should match(%r{A long story\nreally with a comma, a double quote "" and a non-ASCII char éà Über.})
|
61
|
+
graph_from_CSV = described_class.from_CSV(csv)
|
62
|
+
graph_from_CSV.first.should be_equivalent(graph.first)
|
63
|
+
end
|
64
|
+
end
|
48
65
|
end
|
49
66
|
end
|
@@ -36,6 +36,7 @@ module Dbd
|
|
36
36
|
duration.should < 0.000_15 * NUMBER_OF_FACTS
|
37
37
|
# typ. 37 us on Mac Ruby 2.0.0 (on 2013-05-15 over 15K iterations)
|
38
38
|
# typ. 45 us on Mac Ruby 2.0.0 (on 2013-06-05 over 10K iterations)
|
39
|
+
# typ. 47 us on Mac Ruby 2.0.0 (on 2013-06-21 over 10K iterations)
|
39
40
|
# typ. 60 us on Mac jruby 1.7.3
|
40
41
|
end
|
41
42
|
end
|
@@ -6,6 +6,10 @@ module Dbd
|
|
6
6
|
let(:provenance_subject) { Factories::ProvenanceResource.provenance_resource.subject }
|
7
7
|
|
8
8
|
describe "Factories::Resource" do
|
9
|
+
it ".empty works" do
|
10
|
+
Factories::Resource.facts_resource(provenance_subject)
|
11
|
+
end
|
12
|
+
|
9
13
|
it ".facts_resource works" do
|
10
14
|
Factories::Resource.facts_resource(provenance_subject)
|
11
15
|
end
|
@@ -3,9 +3,13 @@ require 'spec_helper'
|
|
3
3
|
module Dbd
|
4
4
|
describe TimeStamp do
|
5
5
|
|
6
|
-
let(:time_stamp_0) { described_class.new(time: Time.
|
7
|
-
let(:time_stamp_1) { described_class.new(time: Time.
|
8
|
-
let(:time_stamp_2) { described_class.new(time: Time.
|
6
|
+
let(:time_stamp_0) { described_class.new(time: Time.utc(2013,5,18,12,0,0)) }
|
7
|
+
let(:time_stamp_1) { described_class.new(time: Time.utc(2013,5,18,12,0,0)) }
|
8
|
+
let(:time_stamp_2) { described_class.new(time: Time.utc(2013,5,18,12,0,1,5_000)) }
|
9
|
+
let(:time_stamp_3) { described_class.new(time: Time.utc(2013,5,18,12,0,1,5_001)) }
|
10
|
+
let(:time_stamp_4) { described_class.new(time: Time.utc(2013,5,18,12,0,1,4_999)) }
|
11
|
+
let(:time_stamp_5) { described_class.new(time: Time.utc(2013,5,18,12,0,1,5_002)) }
|
12
|
+
let(:time_stamp_6) { described_class.new(time: Time.utc(2013,5,18,12,0,1,4_998)) }
|
9
13
|
|
10
14
|
describe "==" do
|
11
15
|
it "should be ==" do
|
@@ -17,6 +21,24 @@ module Dbd
|
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
24
|
+
describe "near?(other)" do
|
25
|
+
it "is true when the time_stamp is 1000 ns larger" do
|
26
|
+
time_stamp_2.near?(time_stamp_3).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is true when the time_stamp is 1000 ns smaller" do
|
30
|
+
time_stamp_2.near?(time_stamp_4).should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "is false when the time_stamp is 2000 ns larger" do
|
34
|
+
time_stamp_2.near?(time_stamp_5).should_not be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "is false when the time_stamp is 2000 ns smaller" do
|
38
|
+
time_stamp_2.near?(time_stamp_6).should_not be_true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
20
42
|
describe ">" do
|
21
43
|
it "is true if time_stamp is really larger" do
|
22
44
|
time_stamp_2.should > time_stamp_1
|
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Dbd
|
4
4
|
describe TimeStamp do
|
5
|
+
|
5
6
|
let(:fixed_time_stamp) { Factories::TimeStamp.fixed_time_stamp }
|
6
7
|
|
7
8
|
describe "factory works" do
|
@@ -10,7 +11,7 @@ module Dbd
|
|
10
11
|
end
|
11
12
|
|
12
13
|
it "has an exact time" do
|
13
|
-
fixed_time_stamp.to_s.should == "2013-06-17 21:55:09.
|
14
|
+
fixed_time_stamp.to_s.should == "2013-06-17 21:55:09.967653013 UTC"
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -25,18 +25,18 @@ module Dbd
|
|
25
25
|
|
26
26
|
describe ".from_s" do
|
27
27
|
it "returns a TimeStamp" do
|
28
|
-
described_class.
|
28
|
+
described_class.new(time: a_time_stamp).should be_a(described_class)
|
29
29
|
end
|
30
30
|
|
31
31
|
it "round trips with to_s" do
|
32
|
-
time_stamp = described_class.
|
32
|
+
time_stamp = described_class.new(time: a_time_stamp)
|
33
33
|
time_stamp.to_s.should == a_time_stamp
|
34
34
|
end
|
35
35
|
|
36
36
|
it "raises ArgumentError is time_zone is not UTC" do
|
37
37
|
time_CET = a_time_stamp.sub(/UTC/, 'CET')
|
38
|
-
lambda{ described_class.
|
38
|
+
lambda{ described_class.new(time: time_CET) }.should raise_error ArgumentError
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
end
|
42
42
|
end
|
@@ -6,6 +6,8 @@ module Dbd
|
|
6
6
|
|
7
7
|
let(:time) { Time.now.utc }
|
8
8
|
|
9
|
+
let(:time_string) { Factories::TimeStamp.fixed_time_string }
|
10
|
+
|
9
11
|
before(:each) do
|
10
12
|
time
|
11
13
|
Time.stub(:now).and_return(time)
|
@@ -15,12 +17,17 @@ module Dbd
|
|
15
17
|
subject # should_not raise_error
|
16
18
|
end
|
17
19
|
|
18
|
-
it "with :time option, sets that to time" do
|
20
|
+
it "with :time option given a Time object, sets that to time" do
|
19
21
|
near_future = time + 100
|
20
22
|
time_stamp = described_class.new(time: near_future)
|
21
23
|
time_stamp.time.should == near_future
|
22
24
|
end
|
23
25
|
|
26
|
+
it "with :time option given a String object, sets that to time" do
|
27
|
+
time_stamp = described_class.new(time: time_string)
|
28
|
+
time_stamp.to_s.should == time_string
|
29
|
+
end
|
30
|
+
|
24
31
|
it "with :larger_than, sets a time that is strictly and slightly larger than this" do
|
25
32
|
larger_than = described_class.new(time: time + Rational('500/1000_000')) # 0.5 ms
|
26
33
|
time_stamp = described_class.new(larger_than: larger_than)
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Vandenabeele
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
11
|
+
date: 2013-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - '
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - '
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rb-fsevent
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: terminal-notifier-guard
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,34 +112,35 @@ dependencies:
|
|
112
112
|
name: rdf
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: '0'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - '>='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: ruby_peter_v
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - '>='
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: 0.0.
|
131
|
+
version: 0.0.9
|
132
132
|
type: :runtime
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
136
|
- - '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 0.0.
|
138
|
+
version: 0.0.9
|
139
139
|
description: A data store that (almost) never forgets
|
140
140
|
email:
|
141
141
|
- peter@vandenabeele.com
|
142
|
-
executables:
|
142
|
+
executables:
|
143
|
+
- test_1.rb
|
143
144
|
extensions: []
|
144
145
|
extra_rdoc_files: []
|
145
146
|
files:
|
@@ -153,6 +154,7 @@ files:
|
|
153
154
|
- LICENSE.txt
|
154
155
|
- README.md
|
155
156
|
- Rakefile
|
157
|
+
- bin/test_1.rb
|
156
158
|
- dbd.gemspec
|
157
159
|
- docs/rationale.md
|
158
160
|
- docs/stories/001_create_a_fact.txt
|