rdf-spec 1.99.0 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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