rdf-spec 1.99.0 → 2.0.0.beta1

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/{README → README.md} +2 -0
  3. data/VERSION +1 -1
  4. data/lib/rdf/spec.rb +18 -0
  5. data/lib/rdf/spec/countable.rb +5 -28
  6. data/lib/rdf/spec/dataset.rb +47 -0
  7. data/lib/rdf/spec/durable.rb +8 -23
  8. data/lib/rdf/spec/enumerable.rb +118 -102
  9. data/lib/rdf/spec/format.rb +4 -26
  10. data/lib/rdf/spec/http_adapter.rb +1 -23
  11. data/lib/rdf/spec/indexable.rb +1 -23
  12. data/lib/rdf/spec/inferable.rb +0 -16
  13. data/lib/rdf/spec/inspects.rb +4 -5
  14. data/lib/rdf/spec/matchers.rb +95 -4
  15. data/lib/rdf/spec/mutable.rb +227 -81
  16. data/lib/rdf/spec/queryable.rb +122 -165
  17. data/lib/rdf/spec/readable.rb +0 -22
  18. data/lib/rdf/spec/reader.rb +21 -29
  19. data/lib/rdf/spec/repository.rb +80 -40
  20. data/lib/rdf/spec/transactable.rb +43 -0
  21. data/lib/rdf/spec/transaction.rb +294 -71
  22. data/lib/rdf/spec/version.rb +2 -2
  23. data/lib/rdf/spec/writable.rb +78 -100
  24. data/lib/rdf/spec/writer.rb +51 -28
  25. data/spec/countable_spec.rb +11 -0
  26. data/spec/dataset_spec.rb +14 -0
  27. data/spec/durable_spec.rb +12 -0
  28. data/spec/enumerable_spec.rb +11 -0
  29. data/spec/format_spec.rb +12 -0
  30. data/spec/http_adapter_spec.rb +15 -0
  31. data/spec/indexable.rb +15 -0
  32. data/spec/literal_spec.rb +75 -0
  33. data/spec/mutable_spec.rb +11 -0
  34. data/spec/queryable_spec.rb +13 -0
  35. data/spec/readable.rb +11 -0
  36. data/spec/reader_spec.rb +17 -0
  37. data/spec/repository_spec.rb +11 -0
  38. data/spec/spec_helper.rb +13 -0
  39. data/spec/transaction_spec.rb +7 -0
  40. data/spec/version_spec.rb +2 -0
  41. data/spec/writable_spec.rb +13 -0
  42. data/spec/writer_spec.rb +11 -0
  43. metadata +56 -12
@@ -26,6 +26,98 @@ RSpec.shared_examples 'an RDF::Queryable' do
26
26
  let(:resource) {RDF::URI('http://rubygems.org/gems/rdf')}
27
27
  let(:literal) {RDF::Literal.new('J. Random Hacker')}
28
28
  let(:query) {RDF::Query.new {pattern [:s, :p, :o]}}
29
+
30
+ shared_examples 'query execution' do |method|
31
+ it "requires an argument" do
32
+ expect { subject.send(method) }.to raise_error(ArgumentError)
33
+ end
34
+
35
+ it "yields to the given block" do
36
+ expect {|b| subject.send(method, query, &b)}.to yield_control.exactly(queryable.count).times
37
+ end
38
+
39
+ it "yields solutions" do
40
+ subject.send(method, query) do |solution|
41
+ expect(solution).to be_a RDF::Query::Solution
42
+ end
43
+ end
44
+ end
45
+
46
+ shared_examples 'query pattern' do |method|
47
+ it "requires an argument" do
48
+ expect { subject.send(method) }.to raise_error(ArgumentError)
49
+ end
50
+
51
+ it "yields to the given block" do
52
+ expect {|b| subject.send(method, RDF::Query::Pattern.new, &b)}.to yield_control.exactly(queryable.count).times
53
+ end
54
+
55
+ it "yields statements" do
56
+ subject.send(method, RDF::Query::Pattern.new) do |statement|
57
+ expect(statement).to be_a_statement
58
+ end
59
+ end
60
+
61
+ context "with specific patterns" do
62
+ # Note that "01" should not match 1, per data-r2/expr-equal/sameTerm
63
+ {
64
+ [RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
65
+ [RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), nil] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
66
+ [RDF::URI("http://example.org/xi1"), nil, 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
67
+ [nil, RDF::URI("http://example.org/p"), 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1]), RDF::Statement.from([RDF::URI("http://example.org/xi2"), RDF::URI("http://example.org/p"), 1])],
68
+ [nil, nil, 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1]), RDF::Statement.from([RDF::URI("http://example.org/xi2"), RDF::URI("http://example.org/p"), 1])],
69
+ [nil, RDF::URI("http://example.org/p"), RDF::Literal::Double.new("1.0e0")] => [RDF::Statement.from([RDF::URI("http://example.org/xd1"), RDF::URI("http://example.org/p"), RDF::Literal::Double.new("1.0e0")])],
70
+ }.each do |pattern, result|
71
+ pattern = RDF::Query::Pattern.from(pattern)
72
+ it "returns #{result.inspect} given #{pattern.inspect}" do
73
+ solutions = []
74
+ subject.send(method, pattern) {|s| solutions << s}
75
+ expect(solutions).to contain_exactly(*result)
76
+ end
77
+ end
78
+ end
79
+
80
+ context "with graph_name" do
81
+ it "returns statements from all graphs with no graph_name" do
82
+ pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: nil)
83
+ solutions = []
84
+ subject.send(method, pattern) {|s| solutions << s}
85
+ expect(solutions.size).to eq @statements.size
86
+ end
87
+
88
+ it "returns statements from unnamed graphs with false graph_name" do
89
+ pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: false)
90
+ solutions = []
91
+ subject.send(method, pattern) {|s| solutions << s}
92
+
93
+ named_statements = subject.statements
94
+ named_statements.reject! {|st| st.has_name?} unless
95
+ subject.respond_to?(:graph_name) && !subject.graph_name.nil?
96
+
97
+ expect(solutions.size).to eq named_statements.size
98
+ end
99
+
100
+ it "returns statements from named graphs with variable graph_name" do
101
+ unless subject.graph_names.to_a.empty?
102
+ pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: :c)
103
+ solutions = []
104
+ subject.send(method, pattern) {|s| solutions << s}
105
+ named_statements = subject.statements.select {|st| st.has_name?}
106
+ expect(solutions.size).to eq named_statements.size
107
+ end
108
+ end
109
+
110
+ it "returns statements from specific graph with URI graph_name" do
111
+ unless subject.graph_names.to_a.empty? ||
112
+ (subject.respond_to?(:graph_name) && !subject.graph_name.nil?)
113
+ pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: RDF::URI("http://ar.to/#self"))
114
+ solutions = []
115
+ subject.send(method, pattern) {|s| solutions << s}
116
+ expect(solutions.size).to eq File.readlines(@doap).grep(/^<http:\/\/ar.to\/\#self>/).size
117
+ end
118
+ end
119
+ end
120
+ end
29
121
 
30
122
  ##
31
123
  # @see RDF::Queryable#query
@@ -33,6 +125,9 @@ RSpec.shared_examples 'an RDF::Queryable' do
33
125
  it {is_expected.to respond_to(:query)}
34
126
 
35
127
  context "when called" do
128
+ include_examples 'query execution', :query
129
+ include_examples 'query pattern', :query
130
+
36
131
  it "requires an argument" do
37
132
  expect { subject.query }.to raise_error(ArgumentError)
38
133
  end
@@ -81,27 +176,20 @@ RSpec.shared_examples 'an RDF::Queryable' do
81
176
  expect(statement).not_to be_a RDF::Query::Solution
82
177
  end
83
178
  end
84
-
85
- it "calls #query_pattern" do
86
- is_expected.to receive(:query_pattern)
87
- is_expected.not_to receive(:query_execute)
88
- subject.query([:s, :p, :o]) {}
89
- end
90
179
  end
91
180
 
92
181
  context "with a Query argument" do
182
+ it "yields to the given block" do
183
+ expect { |b| subject.query(query, &b) }
184
+ .to yield_control.exactly(queryable.count).times
185
+ end
186
+
93
187
  it "yields statements" do
94
188
  subject.query(query) do |solution|
95
189
  expect(solution).not_to be_a_statement
96
190
  expect(solution).to be_a RDF::Query::Solution
97
191
  end
98
192
  end
99
-
100
- it "calls #query_execute" do
101
- is_expected.to receive(:query_execute)
102
- is_expected.not_to receive(:query_pattern)
103
- subject.query(query) {}
104
- end
105
193
  end
106
194
  end
107
195
 
@@ -223,140 +311,26 @@ RSpec.shared_examples 'an RDF::Queryable' do
223
311
  ##
224
312
  # @see RDF::Queryable#query_execute
225
313
  describe "#query_execute" do
314
+ before { skip unless subject.respond_to?(:query_execute, true ) }
315
+
226
316
  it "defines a protected #query_execute method" do
227
- expect(subject.class.protected_method_defined?(:query_execute)).to be_truthy
317
+ expect(subject.class.protected_method_defined?(:query_execute))
318
+ .to be_truthy
228
319
  end
229
320
 
230
- context "when called" do
231
- it "requires an argument" do
232
- expect { subject.send(:query_execute) }.to raise_error(ArgumentError)
233
- end
234
-
235
- it "yields to the given block" do
236
- expect {|b| subject.send(:query_execute, query, &b)}.to yield_control.exactly(queryable.count).times
237
- end
238
-
239
- it "yields solutions" do
240
- subject.send(:query_execute, query) do |solution|
241
- expect(solution).to be_a RDF::Query::Solution
242
- end
243
- end
244
- end
321
+ include_examples 'query execution', :query_execute
245
322
  end
246
323
 
247
324
  ##
248
325
  # @see RDF::Queryable#query_pattern
249
326
  describe "#query_pattern" do
327
+ before { skip unless subject.respond_to?(:query_pattern, true ) }
328
+
250
329
  it "defines a protected #query_pattern method" do
251
330
  expect(subject.class.protected_method_defined?(:query_pattern)).to be_truthy
252
331
  end
253
-
254
- context "when called" do
255
- it "requires an argument" do
256
- expect { subject.send(:query_pattern) }.to raise_error(ArgumentError)
257
- end
258
-
259
- it "yields to the given block" do
260
- expect {|b| subject.send(:query_pattern, RDF::Query::Pattern.new, &b)}.to yield_control.exactly(queryable.count).times
261
- end
262
-
263
- it "yields statements" do
264
- subject.send(:query_pattern, RDF::Query::Pattern.new) do |statement|
265
- expect(statement).to be_a_statement
266
- end
267
- end
268
-
269
- context "with specific patterns" do
270
- # Note that "01" should not match 1, per data-r2/expr-equal/sameTerm
271
- {
272
- [RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
273
- [RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), nil] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
274
- [RDF::URI("http://example.org/xi1"), nil, 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1])],
275
- [nil, RDF::URI("http://example.org/p"), 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1]), RDF::Statement.from([RDF::URI("http://example.org/xi2"), RDF::URI("http://example.org/p"), 1])],
276
- [nil, nil, 1] => [RDF::Statement.from([RDF::URI("http://example.org/xi1"), RDF::URI("http://example.org/p"), 1]), RDF::Statement.from([RDF::URI("http://example.org/xi2"), RDF::URI("http://example.org/p"), 1])],
277
- [nil, RDF::URI("http://example.org/p"), RDF::Literal::Double.new("1.0e0")] => [RDF::Statement.from([RDF::URI("http://example.org/xd1"), RDF::URI("http://example.org/p"), RDF::Literal::Double.new("1.0e0")])],
278
- }.each do |pattern, result|
279
- pattern = RDF::Query::Pattern.from(pattern)
280
- it "returns #{result.inspect} given #{pattern.inspect}" do
281
- solutions = []
282
- subject.send(:query_pattern, pattern) {|s| solutions << s}
283
- expect(solutions).to eq result
284
- end
285
- end
286
- end
287
-
288
- context "with context", unless: RDF::VERSION.to_s >= "1.99" do
289
- it "returns statements from all contexts with no context" do
290
- pattern = RDF::Query::Pattern.new(nil, nil, nil, context: nil)
291
- solutions = []
292
- subject.send(:query_pattern, pattern) {|s| solutions << s}
293
- expect(solutions.size).to eq @statements.size
294
- end
295
-
296
- it "returns statements from unnamed contexts with false context" do
297
- pattern = RDF::Query::Pattern.new(nil, nil, nil, context: false)
298
- solutions = []
299
- subject.send(:query_pattern, pattern) {|s| solutions << s}
300
- context_statements = subject.statements.reject {|st| st.has_context?}.length
301
- expect(solutions.size).to eq context_statements
302
- end
303
-
304
- it "returns statements from named contexts with variable context" do
305
- unless subject.contexts.to_a.empty?
306
- pattern = RDF::Query::Pattern.new(nil, nil, nil, context: :c)
307
- solutions = []
308
- subject.send(:query_pattern, pattern) {|s| solutions << s}
309
- context_statements = subject.statements.select {|st| st.has_context?}.length
310
- expect(solutions.size).to eq context_statements
311
- end
312
- end
313
-
314
- it "returns statements from specific context with URI context" do
315
- unless subject.contexts.to_a.empty?
316
- pattern = RDF::Query::Pattern.new(nil, nil, nil, context: RDF::URI("http://ar.to/#self"))
317
- solutions = []
318
- subject.send(:query_pattern, pattern) {|s| solutions << s}
319
- expect(solutions.size).to eq File.readlines(@doap).grep(/^<http:\/\/ar.to\/\#self>/).size
320
- end
321
- end
322
- end
323
-
324
- context "with graph_name", if: RDF::VERSION.to_s >= "1.99" do
325
- it "returns statements from all graphs with no graph_name" do
326
- pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: nil)
327
- solutions = []
328
- subject.send(:query_pattern, pattern) {|s| solutions << s}
329
- expect(solutions.size).to eq @statements.size
330
- end
331
-
332
- it "returns statements from unnamed graphss with false graph_name" do
333
- pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: false)
334
- solutions = []
335
- subject.send(:query_pattern, pattern) {|s| solutions << s}
336
- named_statements = subject.statements.reject {|st| st.has_name?}.length
337
- expect(solutions.size).to eq named_statements
338
- end
339
-
340
- it "returns statements from named graphss with variable graph_name" do
341
- unless subject.graph_names.to_a.empty?
342
- pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: :c)
343
- solutions = []
344
- subject.send(:query_pattern, pattern) {|s| solutions << s}
345
- named_statements = subject.statements.select {|st| st.has_name?}.length
346
- expect(solutions.size).to eq named_statements
347
- end
348
- end
349
-
350
- it "returns statements from specific graph with URI graph_name" do
351
- unless subject.graph_names.to_a.empty?
352
- pattern = RDF::Query::Pattern.new(nil, nil, nil, graph_name: RDF::URI("http://ar.to/#self"))
353
- solutions = []
354
- subject.send(:query_pattern, pattern) {|s| solutions << s}
355
- expect(solutions.size).to eq File.readlines(@doap).grep(/^<http:\/\/ar.to\/\#self>/).size
356
- end
357
- end
358
- end
359
- end
332
+
333
+ include_examples 'query pattern', :query_pattern
360
334
  end
361
335
 
362
336
  ##
@@ -405,10 +379,11 @@ RSpec.shared_examples 'an RDF::Queryable' do
405
379
  expect(subject.first_subject).to eq subject.first.subject
406
380
  end
407
381
 
408
- it "returns the correct value when the pattern matches" do
382
+ it "returns an appropriate value when the pattern matches" do
409
383
  matching_patterns = [[nil, nil, nil], [RDF::URI("http://rubygems.org/gems/rdf"), nil, nil]]
410
384
  matching_patterns.each do |matching_pattern|
411
- expect(subject.first_subject(matching_pattern)).to eq subject.query(matching_pattern).first.subject
385
+ matching_values = subject.query(matching_pattern).map(&:subject)
386
+ expect(matching_values).to include subject.first_subject(matching_pattern)
412
387
  end
413
388
  end
414
389
 
@@ -436,10 +411,11 @@ RSpec.shared_examples 'an RDF::Queryable' do
436
411
  expect(subject.first_predicate).to eq subject.first.predicate
437
412
  end
438
413
 
439
- it "returns the correct value when the pattern matches" do
414
+ it "returns an appropriate value when the pattern matches" do
440
415
  matching_patterns = [[nil, nil, nil], [nil, subject.first.predicate, nil]]
441
416
  matching_patterns.each do |matching_pattern|
442
- expect(subject.first_predicate(matching_pattern)).to eq subject.query(matching_pattern).first.predicate
417
+ matching_values = subject.query(matching_pattern).map(&:predicate)
418
+ expect(matching_values).to include subject.first_predicate(matching_pattern)
443
419
  end
444
420
  end
445
421
 
@@ -466,10 +442,11 @@ RSpec.shared_examples 'an RDF::Queryable' do
466
442
  expect(subject.first_object).to eq subject.first.object
467
443
  end
468
444
 
469
- it "returns the correct value when the pattern matches" do
445
+ it "returns an appropriate value when the pattern matches" do
470
446
  matching_patterns = [[nil, nil, nil], [nil, nil, subject.first.object]]
471
447
  matching_patterns.each do |matching_pattern|
472
- expect(subject.first_object(matching_pattern)).to eq subject.query(matching_pattern).first.object
448
+ matching_values = subject.query(matching_pattern).map(&:object)
449
+ expect(matching_values).to include subject.first_object(matching_pattern)
473
450
  end
474
451
  end
475
452
 
@@ -534,14 +511,16 @@ RSpec.shared_examples 'an RDF::Queryable' do
534
511
  expect(subject.first_value).to eq subject.first_literal.value
535
512
  end
536
513
 
537
- it "returns the correct value when the pattern matches" do
514
+ it "returns an appropriate value when the pattern matches" do
538
515
  matching_patterns = []
539
516
  subject.each do |statement|
540
517
  if statement.object.is_a?(RDF::Literal)
541
518
  matching_pattern = [statement.subject, statement.predicate, nil]
542
519
  unless matching_patterns.include?(matching_pattern)
543
520
  matching_patterns << matching_pattern
544
- expect(subject.first_value(matching_pattern)).to eq subject.first_literal(matching_pattern).value
521
+ matching_values = subject.query(matching_pattern).map(&:object).map(&:value)
522
+ first_value = subject.first_value(matching_pattern)
523
+ expect(matching_values).to include(first_value)
545
524
  end
546
525
  end
547
526
  end
@@ -559,25 +538,3 @@ RSpec.shared_examples 'an RDF::Queryable' do
559
538
  end
560
539
  end
561
540
  end
562
-
563
- ##
564
- # @deprecated use `it_behaves_like "an RDF::Queryable"` instead
565
- module RDF_Queryable
566
- extend RSpec::SharedContext
567
- include RDF::Spec::Matchers
568
-
569
- def self.included(mod)
570
- warn "[DEPRECATION] `RDF_Queryable` is deprecated. "\
571
- "Please use `it_behaves_like 'an RDF::Queryable'`"
572
- end
573
-
574
- describe 'examples for' do
575
- include_examples 'an RDF::Queryable' do
576
- let(:queryable) { @queryable }
577
-
578
- before do
579
- raise '@queryable must be defined' unless defined?(queryable)
580
- end
581
- end
582
- end
583
- end
@@ -15,25 +15,3 @@ RSpec.shared_examples 'an RDF::Readable' do
15
15
  its(:readable?) { is_expected.to eq subject.readable? }
16
16
  end
17
17
  end
18
-
19
- ##
20
- # @deprecated use `it_behaves_like "an RDF::Readable"` instead
21
- module RDF_Readable
22
- extend RSpec::SharedContext
23
- include RDF::Spec::Matchers
24
-
25
- def self.included(mod)
26
- warn "[DEPRECATION] `RDF_Readable` is deprecated. "\
27
- "Please use `it_behaves_like 'an RDF::Readable'`"
28
- end
29
-
30
- describe 'examples for' do
31
- include_examples 'an RDF::Readable' do
32
- let(:readable) { @readable }
33
-
34
- before do
35
- raise '@readable must be defined' unless defined?(readable)
36
- end
37
- end
38
- end
39
- end
@@ -7,6 +7,7 @@ RSpec.shared_examples 'an RDF::Reader' do
7
7
  raise 'reader must be defined with let(:reader)' unless defined? reader
8
8
  raise 'reader_input must be defined with let(:reader_input)' unless defined? reader_input
9
9
  raise 'reader_count must be defined with let(:reader_count)' unless defined? reader_count
10
+ # define reader_invalid_input for invalid input
10
11
  end
11
12
 
12
13
  let(:reader_class) { reader.class }
@@ -107,12 +108,31 @@ RSpec.shared_examples 'an RDF::Reader' do
107
108
  end
108
109
  end
109
110
 
110
- it "sets validate given validate: true" do
111
+ it "validates given validate: true" do
111
112
  reader_class.new(reader_input, validate: true) do |r|
112
113
  expect(r).to be_valid
113
114
  end
114
115
  end
115
116
 
117
+ it "invalidates on any logged error if validate: true" do
118
+ logger = RDF::Spec.logger
119
+ reader_class.new(reader_input, validate: true, logger: logger) do |r|
120
+ expect(r).to be_valid
121
+ r.log_error("some error")
122
+ expect(r).not_to be_valid
123
+ end
124
+ expect(logger.to_s).to include("ERROR")
125
+ end
126
+
127
+ it "invalidates given invalid input and validate: true" do
128
+ invalid_input = reader_invalid_input rescue "!!invalid input??"
129
+ logger = RDF::Spec.logger
130
+ reader_class.new(invalid_input, validate: true, logger: logger) do |r|
131
+ expect(r).not_to be_valid
132
+ expect(logger.to_s).to include("ERROR")
133
+ end
134
+ end
135
+
116
136
  it "sets canonicalize given canonicalize: true" do
117
137
  reader_mock = double("reader")
118
138
  expect(reader_mock).to receive(:got_here)
@@ -204,31 +224,3 @@ RSpec.shared_examples 'an RDF::Reader' do
204
224
 
205
225
  end
206
226
  end
207
-
208
- ##
209
- # @deprecated use `it_behaves_like "an RDF::Reader"` instead
210
- module RDF_Reader
211
- extend RSpec::SharedContext
212
- include RDF::Spec::Matchers
213
-
214
- def self.included(mod)
215
- warn "[DEPRECATION] `RDF_Reader` is deprecated. "\
216
- "Please use `it_behaves_like 'an RDF::Reader'`"
217
- end
218
-
219
- describe 'examples for' do
220
- include_examples 'an RDF::Reader' do
221
- let(:reader) { @reader }
222
- let(:reader_input) { @reader_input }
223
- let(:reader_count) { @reader_count }
224
- let(:reader_class) { @reader_class }
225
-
226
- before do
227
- raise '@reader must be defined' unless defined?(reader)
228
- raise '@reader_input must be defined' unless defined?(reader_input)
229
- raise '@reader_count must be defined' unless defined?(reader_count)
230
- raise '@reader_class must be defined' unless defined?(reader_class)
231
- end
232
- end
233
- end
234
- end