rdf-ldp 0.9.2 → 2.1.0

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.
@@ -0,0 +1,242 @@
1
+ require 'rspec'
2
+ require 'rdf/spec'
3
+ require 'rdf/spec/matchers'
4
+ require 'timecop'
5
+
6
+ shared_examples 'a Resource' do
7
+ describe '.to_uri' do
8
+ it { expect(described_class.to_uri).to be_a RDF::URI }
9
+ end
10
+
11
+ subject { described_class.new(uri) }
12
+ let(:uri) { RDF::URI 'http://example.org/moomin' }
13
+
14
+ it { is_expected.to be_ldp_resource }
15
+ it { is_expected.to respond_to :container? }
16
+ it { is_expected.to respond_to :rdf_source? }
17
+ it { is_expected.to respond_to :non_rdf_source? }
18
+
19
+ it { subject.send(:set_last_modified) }
20
+
21
+ describe '#exists?' do
22
+ it 'does not exist' do
23
+ expect(subject).not_to exist
24
+ end
25
+
26
+ context 'while existing' do
27
+ before { subject.create(StringIO.new, 'application/n-triples') }
28
+
29
+ subject { described_class.new(uri, repository) }
30
+ let(:repository) { RDF::Repository.new }
31
+
32
+ it 'exists' do
33
+ expect(subject).to exist
34
+ end
35
+
36
+ it 'is different from same URI with trailing /' do
37
+ expect(described_class.new(uri + '/', repository)).not_to exist
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '#allowed_methods' do
43
+ it 'responds to all methods returned' do
44
+ subject.allowed_methods.each do |method|
45
+ expect(subject.respond_to?(method.downcase, true)).to be true
46
+ end
47
+ end
48
+
49
+ it 'includes the MUST methods' do
50
+ expect(subject.allowed_methods).to include(:GET, :OPTIONS, :HEAD)
51
+ end
52
+ end
53
+
54
+ describe '#create' do
55
+ it 'accepts two args' do
56
+ expect(described_class.instance_method(:create).arity).to eq 2
57
+ end
58
+
59
+ describe 'modified time' do
60
+ before { Timecop.freeze }
61
+ after { Timecop.return }
62
+
63
+ it 'sets last_modified' do
64
+ subject.create(StringIO.new, 'text/turtle')
65
+ expect(subject.last_modified).to eq DateTime.now
66
+ end
67
+ end
68
+
69
+ it 'adds a type triple to metagraph' do
70
+ subject.create(StringIO.new, 'application/n-triples')
71
+ expect(subject.metagraph)
72
+ .to have_statement RDF::Statement(subject.subject_uri,
73
+ RDF.type,
74
+ described_class.to_uri)
75
+ end
76
+
77
+ it 'yields a transaction' do
78
+ expect { |b| subject.create(StringIO.new, 'application/n-triples', &b) }
79
+ .to yield_with_args(be_kind_of(RDF::Transaction))
80
+ end
81
+
82
+ it 'marks resource as existing' do
83
+ expect { subject.create(StringIO.new, 'application/n-triples') }
84
+ .to change { subject.exists? }.from(false).to(true)
85
+ end
86
+
87
+ it 'returns self' do
88
+ expect(subject.create(StringIO.new, 'application/n-triples'))
89
+ .to eq subject
90
+ end
91
+
92
+ it 'raises Conlict when already exists' do
93
+ subject.create(StringIO.new, 'application/n-triples')
94
+ expect { subject.create(StringIO.new, 'application/n-triples') }
95
+ .to raise_error RDF::LDP::Conflict
96
+ end
97
+ end
98
+
99
+ describe '#update' do
100
+ it 'accepts two args' do
101
+ expect(described_class.instance_method(:update).arity).to eq 2
102
+ end
103
+
104
+ it 'returns self' do
105
+ expect(subject.update(StringIO.new, 'application/n-triples'))
106
+ .to eq subject
107
+ end
108
+
109
+ it 'yields a changeset' do
110
+ expect { |b| subject.update(StringIO.new, 'application/n-triples', &b) }
111
+ .to yield_with_args(be_kind_of(RDF::Transaction))
112
+ end
113
+ end
114
+
115
+ describe '#destroy' do
116
+ it 'accepts no args' do
117
+ expect(described_class.instance_method(:destroy).arity).to eq 0
118
+ end
119
+ end
120
+
121
+ describe '#metagraph' do
122
+ it 'returns a graph' do
123
+ expect(subject.metagraph).to be_a RDF::Graph
124
+ end
125
+
126
+ it 'has the metagraph name for the resource' do
127
+ expect(subject.metagraph.graph_name).to eq subject.subject_uri / '#meta'
128
+ end
129
+ end
130
+
131
+ describe '#etag' do
132
+ before { subject.create(StringIO.new, 'application/n-triples') }
133
+
134
+ it 'has an etag' do
135
+ expect(subject.etag).to be_a String
136
+ end
137
+
138
+ it 'updates etag on change' do
139
+ expect { subject.update(StringIO.new, 'application/n-triples') }
140
+ .to change { subject.etag }
141
+ end
142
+ end
143
+
144
+ describe '#last_modified' do
145
+ it 'returns nil when no dc:modified triple is present' do
146
+ expect(subject.last_modified).to be_nil
147
+ end
148
+
149
+ it 'raises an error when exists without dc:modified triple is present' do
150
+ allow(subject).to receive(:exists?).and_return true
151
+ expect { subject.last_modified }.to raise_error RDF::LDP::RequestError
152
+ end
153
+
154
+ context 'with dc:modified triple' do
155
+ before do
156
+ subject.metagraph.update([subject.subject_uri,
157
+ RDF::Vocab::DC.modified,
158
+ datetime])
159
+ end
160
+
161
+ let(:datetime) { DateTime.now }
162
+
163
+ it 'returns date in `dc:modified`' do
164
+ expect(subject.last_modified).to eq datetime
165
+ end
166
+ end
167
+ end
168
+
169
+ describe '#to_response' do
170
+ it 'returns an object that responds to #each' do
171
+ expect(subject.to_response).to respond_to :each
172
+ end
173
+ end
174
+
175
+ describe '#request' do
176
+ it 'sends the message to itself' do
177
+ expect(subject).to receive(:blah)
178
+ subject.request(:BLAH, 200, {}, {})
179
+ end
180
+
181
+ it 'raises MethodNotAllowed when method is unimplemented' do
182
+ allow(subject).to receive(:not_implemented)
183
+ .and_raise NotImplementedError
184
+ expect { subject.request(:not_implemented, 200, {}, {}) }
185
+ .to raise_error(RDF::LDP::MethodNotAllowed)
186
+ end
187
+
188
+ [:GET, :OPTIONS, :HEAD].each do |method|
189
+ it "responds to #{method}" do
190
+ expect(subject.request(method, 200, {}, {}).size).to eq 3
191
+ end
192
+ end
193
+
194
+ [:PATCH, :POST, :PUT, :DELETE, :TRACE, :CONNECT].each do |method|
195
+ it "responds to or errors on #{method}" do
196
+ g = RDF::Graph.new << [RDF::Node.new, RDF.type, 'moomin']
197
+ env = { 'CONTENT_TYPE' => 'application/n-triples',
198
+ 'rack.input' => StringIO.new(g.dump(:ntriples)) }
199
+
200
+ begin
201
+ response = subject.request(method, 200, {}, env)
202
+ expect(response.size).to eq 3
203
+ rescue => e
204
+ expect(e).to be_a RDF::LDP::RequestError
205
+ end
206
+ end
207
+ end
208
+
209
+ describe 'HTTP headers' do
210
+ before { subject.create(StringIO.new, 'text/turtle') }
211
+ let(:headers) { subject.request(:GET, 200, {}, {})[1] }
212
+
213
+ it 'has ETag' do
214
+ expect(headers['ETag']).to eq subject.etag
215
+ end
216
+
217
+ it 'has Last-Modified' do
218
+ expect(headers['Last-Modified']).to eq subject.last_modified.httpdate
219
+ end
220
+
221
+ it 'has Allow' do
222
+ expect(headers['Allow']).to be_a String
223
+ end
224
+
225
+ it 'has Link' do
226
+ expect(headers['Link']).to be_a String
227
+ end
228
+ end
229
+
230
+ it 'responds to :GET' do
231
+ expect { subject.request(:GET, 200, {}, {}) }.not_to raise_error
232
+ end
233
+
234
+ it 'responds to :HEAD' do
235
+ expect { subject.request(:OPTIONS, 200, {}, {}) }.not_to raise_error
236
+ end
237
+
238
+ it 'responds to :OPTIONS' do
239
+ expect { subject.request(:OPTIONS, 200, {}, {}) }.not_to raise_error
240
+ end
241
+ end
242
+ end
@@ -0,0 +1,6 @@
1
+ require 'rdf/ldp/spec/resource'
2
+ require 'rdf/ldp/spec/rdf_source'
3
+ require 'rdf/ldp/spec/non_rdf_source'
4
+ require 'rdf/ldp/spec/container'
5
+ require 'rdf/ldp/spec/direct_container'
6
+ require 'rdf/ldp/spec/indirect_container'
@@ -63,7 +63,7 @@ module RDF::LDP
63
63
  #
64
64
  # @return [IO] an object conforming to the Ruby IO interface
65
65
  def io(&block)
66
- FileUtils.mkdir_p(path_dir) unless Dir.exists?(path_dir)
66
+ FileUtils.mkdir_p(path_dir) unless Dir.exist?(path_dir)
67
67
  FileUtils.touch(path) unless file_exists?
68
68
 
69
69
  File.open(path, 'r+b', &block)
@@ -72,7 +72,7 @@ module RDF::LDP
72
72
  ##
73
73
  # @return [Boolean] 1 if the file has been deleted, otherwise false
74
74
  def delete
75
- return false unless File.exists?(path)
75
+ return false unless File.exist?(path)
76
76
  File.delete(path)
77
77
  end
78
78
 
@@ -81,7 +81,7 @@ module RDF::LDP
81
81
  ##
82
82
  # @return [Boolean]
83
83
  def file_exists?
84
- File.exists?(path)
84
+ File.exist?(path)
85
85
  end
86
86
 
87
87
  ##
@@ -99,4 +99,4 @@ module RDF::LDP
99
99
  end
100
100
  end
101
101
  end
102
- end
102
+ end
@@ -1,4 +1,11 @@
1
1
  module RDF::LDP
2
+ ##
3
+ # Version Number
4
+ #
5
+ # @example getting a version string
6
+ # RDF::LDP::VERSION # or
7
+ # "#{RDF::LDP::VERSION}"
8
+ #
2
9
  module VERSION
3
10
  FILE = File.expand_path('../../../../VERSION', __FILE__)
4
11
  MAJOR, MINOR, TINY, EXTRA = File.read(FILE).chomp.split('.')
@@ -6,14 +13,20 @@ module RDF::LDP
6
13
 
7
14
  ##
8
15
  # @return [String]
9
- def self.to_s() STRING end
16
+ def self.to_s
17
+ STRING
18
+ end
10
19
 
11
20
  ##
12
21
  # @return [String]
13
- def self.to_str() STRING end
22
+ def self.to_str
23
+ STRING
24
+ end
14
25
 
15
26
  ##
16
27
  # @return [Array(Integer, Integer, Integer)]
17
- def self.to_a() [MAJOR, MINOR, TINY] end
28
+ def self.to_a
29
+ [MAJOR, MINOR, TINY]
30
+ end
18
31
  end
19
32
  end
data/lib/rdf/ldp.rb CHANGED
@@ -19,14 +19,15 @@ module RDF
19
19
  # Rack servers.
20
20
  #
21
21
  # @see RDF::LDP::Resource
22
- # @see http://www.w3.org/TR/ldp/ for the Linked Data platform specification
22
+ # @see https://www.w3.org/TR/ldp/ for the Linked Data platform specification
23
23
  module LDP
24
24
  InteractionModel.register(RDF::LDP::RDFSource, default: true)
25
- InteractionModel.register(RDF::LDP::Container, for: RDF::Vocab::LDP.BasicContainer)
25
+ InteractionModel.register(RDF::LDP::Container,
26
+ for: RDF::Vocab::LDP.BasicContainer)
26
27
  InteractionModel.register(RDF::LDP::DirectContainer)
27
28
  InteractionModel.register(RDF::LDP::IndirectContainer)
28
29
  InteractionModel.register(RDF::LDP::NonRDFSource)
29
-
30
+
30
31
  CONTAINER_CLASSES = {
31
32
  basic: RDF::Vocab::LDP.BasicContainer.freeze,
32
33
  direct: RDF::LDP::DirectContainer.to_uri.freeze,