diff --git a/.travis.yml b/.travis.yml index f5b20ae..3e17ac6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,20 @@ language: ruby bundler_args: --without debug script: "bundle exec rspec spec" +before_install: "gem update --system" env: - CI=true rvm: - - 2.2.6 - - 2.3.3 - - 2.4.0 - - jruby - - rbx + - 2.2 + - 2.3 + - 2.4 + - 2.5 + - jruby-9 + - rbx-3 cache: bundler sudo: false matrix: allow_failures: - - rvm: rbx - - rvm: jruby + - rvm: jruby-9 + - rvm: rbx-3 +dist: trusty diff --git a/README.md b/README.md index 5361fe3..500695c 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ Note that in most cases, if the instance is empty and mutable, the appropriate s ## Dependencies -* [RDF.rb](http://rubygems.org/gems/rdf) (~> 2.0) -* [RSpec](http://rubygems.org/gems/rspec) (~> 3.0) +* [RDF.rb](http://rubygems.org/gems/rdf) (~> 3.0) +* [RSpec](http://rubygems.org/gems/rspec) (~> 3.7) ## Installation diff --git a/VERSION b/VERSION index ccbccc3..4a36342 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.0 +3.0.0 diff --git a/etc/doap.nt b/etc/doap.nt index 752f1e4..c1b62a5 100644 --- a/etc/doap.nt +++ b/etc/doap.nt @@ -38,8 +38,8 @@ _:g70121455472480 "bedbbf2451e5beb38d59 . . . - . - . + . + . . . . diff --git a/etc/quads.nq b/etc/quads.nq index f1d5016..13db410 100644 --- a/etc/quads.nq +++ b/etc/quads.nq @@ -38,7 +38,7 @@ _:g70121455472480 "bedbbf2451e5beb38d59 . . . - . + . . . . diff --git a/etc/triples.nt b/etc/triples.nt index f608631..21f02d0 100644 --- a/etc/triples.nt +++ b/etc/triples.nt @@ -38,7 +38,7 @@ _:g70121455472480 "bedbbf2451e5beb38d59 . . . - . + . . . . diff --git a/lib/rdf/spec.rb b/lib/rdf/spec.rb index 5ee57be..df59677 100644 --- a/lib/rdf/spec.rb +++ b/lib/rdf/spec.rb @@ -3,6 +3,8 @@ require 'rspec' # @see http://rubygems.org/gems/rspec require 'rdf/spec/inspects' require 'rspec/its' +require 'webmock' +WebMock.allow_net_connect! module RDF ## diff --git a/lib/rdf/spec/enumerable.rb b/lib/rdf/spec/enumerable.rb index 4cf0d37..7e934e8 100644 --- a/lib/rdf/spec/enumerable.rb +++ b/lib/rdf/spec/enumerable.rb @@ -514,23 +514,11 @@ context "when converting" do it {is_expected.to respond_to(:to_h)} it {is_expected.not_to respond_to(:to_hash)} - its(:to_hash) { - expect { - is_expected.to be_instance_of(Hash) - }.to write("DEPRECATION").to(:error) - } describe "#to_h" do it "should have as many keys as subjects" do expect(subject.to_h.keys.size).to eq enumerable.subjects.to_a.size end end - describe "#to_h" do - it "should have as many keys as subjects (with deprecation)" do - expect { - expect(subject.to_hash.keys.size).to eq enumerable.subjects.to_a.size - }.to write("DEPRECATION").to(:error) - end - end end context "when dumping" do diff --git a/lib/rdf/spec/http_adapter.rb b/lib/rdf/spec/http_adapter.rb index 2475e59..97ba7b8 100644 --- a/lib/rdf/spec/http_adapter.rb +++ b/lib/rdf/spec/http_adapter.rb @@ -9,6 +9,8 @@ raise '`http_adapter` must be defined with `let(:http_adapter`' unless defined? http_adapter end + before(:each) {WebMock.disable_net_connect!} + after(:each) {WebMock.allow_net_connect!} let(:uri) {"http://ruby-rdf.github.com/rdf/etc/doap.nt"} diff --git a/lib/rdf/spec/matchers.rb b/lib/rdf/spec/matchers.rb index a712a26..9e05746 100644 --- a/lib/rdf/spec/matchers.rb +++ b/lib/rdf/spec/matchers.rb @@ -269,20 +269,6 @@ def io_name RSpec::Matchers.define :be_equivalent_graph do |expected, info| match do |actual| - def normalize(graph) - case graph - when RDF::Enumerable then graph - when IO, StringIO - RDF::Repository.new(graph, base_uri: @info.action) - else - # Figure out which parser to use - r = RDF::Repository.new - reader_class = RDF::Reader.for() {graph} - reader_class.new(graph, base_uri: @info.action).each {|s| r << s} - r - end - end - @info = if (info.id rescue false) info elsif info.is_a?(Logger) @@ -314,6 +300,33 @@ def normalize(graph) "Results:\n#{@actual.dump(format, standard_prefixes: true, literal_shorthand: false, validate: false) rescue @actual.inspect}" + "\nDebug:\n#{@info.logger}" end + + failure_message_when_negated do |actual| + format = case + when RDF.const_defined?(:TriG) then :trig + when RDF.const_defined?(:Turtle) then :ttl + else :nquads + end + info = @info.respond_to?(:information) ? @info.information : @info.inspect + "Graphs identical\n" + + "\n#{info + "\n" unless info.empty?}" + + "Results:\n#{actual.dump(format, standard_prefixes: true, literal_shorthand: false, validate: false) rescue @actual.inspect}" + + "\nDebug:\n#{@info.logger}" + end + + def normalize(graph) + case graph + when RDF::Enumerable then graph + when IO, StringIO + RDF::Repository.new(graph, base_uri: @info.action) + else + # Figure out which parser to use + r = RDF::Repository.new + reader_class = RDF::Reader.for() {graph} + reader_class.new(graph, base_uri: @info.action).each {|s| r << s} + r + end + end end require 'json' @@ -347,6 +360,15 @@ def normalize(graph) "\n#{info + "\n" unless info.empty?}" + "\nDebug:\n#{@info.logger}" end + + failure_message_when_negated do |actual| + info = @info.respond_to?(:information) ? @info.information : @info.inspect + + "Expected not to produce the following:\n" + + "Actual : #{actual.is_a?(String) ? actual : actual.to_json(JSON_STATE) rescue 'malformed json'}\n" + + "\n#{info + "\n" unless info.empty?}" + + "\nDebug:\n#{@info.logger}" + end end end # Matchers diff --git a/lib/rdf/spec/reader.rb b/lib/rdf/spec/reader.rb index 8e5a206..42a4d10 100644 --- a/lib/rdf/spec/reader.rb +++ b/lib/rdf/spec/reader.rb @@ -1,4 +1,5 @@ require 'rdf/spec' +require 'webmock/rspec' RSpec.shared_examples 'an RDF::Reader' do include RDF::Spec::Matchers @@ -9,8 +10,11 @@ raise 'reader_count must be defined with let(:reader_count)' unless defined? reader_count # define reader_invalid_input for invalid input end + before(:each) {WebMock.disable_net_connect!} + after(:each) {WebMock.allow_net_connect!} let(:reader_class) { reader.class } + let(:format_class) { reader_class.format } describe ".each" do it "yields each reader" do @@ -21,70 +25,117 @@ end describe ".open" do - before(:each) do - allow(RDF::Util::File).to receive(:open_file).and_yield(StringIO.new(reader_input)) - end - it "yields reader given file_name" do - reader_class.format.each do |f| - f.file_extensions.each_pair do |sym, content_type| - reader_mock = double("reader") - expect(reader_mock).to receive(:got_here) - expect(reader_class).to receive(:for).with(file_name: "foo.#{sym}").and_return(reader_class) - reader_class.open("foo.#{sym}") do |r| - expect(r).to be_a(RDF::Reader) - reader_mock.got_here - end + allow(RDF::Util::File).to receive(:open_file).and_yield(StringIO.new(reader_input)) + format_class.file_extensions.each_pair do |sym, content_type| + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + expect(RDF::Reader).to receive(:for).with(file_name: "foo.#{sym}").and_return(reader_class) + RDF::Reader.open("foo.#{sym}") do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here end end end it "yields reader given symbol" do - reader_class.format.each do |f| - sym = f.to_sym # Like RDF::NTriples::Format => :ntriples + allow(RDF::Util::File).to receive(:open_file).and_yield(StringIO.new(reader_input)) + sym = format_class.to_sym # Like RDF::NTriples::Format => :ntriples + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + expect(RDF::Reader).to receive(:for).with(sym).and_return(reader_class) + RDF::Reader.open("foo.#{sym}", format: sym) do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here + end + end + + it "yields reader given {file_name: file_name}" do + allow(RDF::Util::File).to receive(:open_file).and_yield(StringIO.new(reader_input)) + format_class.file_extensions.each_pair do |sym, content_type| reader_mock = double("reader") expect(reader_mock).to receive(:got_here) - expect(reader_class).to receive(:for).with(sym).and_return(reader_class) - reader_class.open("foo.#{sym}", format: sym) do |r| - expect(r).to be_a(RDF::Reader) + expect(RDF::Reader).to receive(:for).with(file_name: "foo.#{sym}").and_return(reader_class) + RDF::Reader.open("foo.#{sym}", file_name: "foo.#{sym}") do |r| + expect(r).to be_a(reader_class) reader_mock.got_here end end end - it "yields reader given {file_name: file_name}" do - reader_class.format.each do |f| - f.file_extensions.each_pair do |sym, content_type| - reader_mock = double("reader") - expect(reader_mock).to receive(:got_here) - expect(reader_class).to receive(:for).with(file_name: "foo.#{sym}").and_return(reader_class) - reader_class.open("foo.#{sym}", file_name: "foo.#{sym}") do |r| - expect(r).to be_a(RDF::Reader) - reader_mock.got_here - end + it "yields reader given {content_type: 'a/b'}" do + allow(RDF::Util::File).to receive(:open_file).and_yield(StringIO.new(reader_input)) + format_class.content_types.each_pair do |content_type, formats| + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + expect(RDF::Reader).to receive(:for).with(content_type: content_type, file_name: "foo").and_return(reader_class) + RDF::Reader.open("foo", content_type: content_type) do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here end end end - it "yields reader given {content_type: 'a/b'}" do - reader_class.format.each do |f| - f.content_types.each_pair do |content_type, formats| - reader_mock = double("reader") - expect(reader_mock).to receive(:got_here) - expect(reader_class).to receive(:for).with(content_type: content_type, file_name: "foo").and_return(reader_class) - reader_class.open("foo", content_type: content_type) do |r| - expect(r).to be_a(RDF::Reader) - reader_mock.got_here - end + it "yields reader when returned content_type matches" do + format_class.content_types.each_pair do |content_type, formats| + uri = "http://example/foo" + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + expect(RDF::Reader).to receive(:for).and_return(reader_class) + + WebMock.stub_request(:get, uri). + to_return(body: "BODY", + status: 200, + headers: { 'Content-Type' => content_type}) + + RDF::Reader.open(uri) do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here end end end + + it "sets Accept header from reader" do + uri = "http://example/foo" + accept = (format_class.accept_type + %w(*/*;q=0.1)).join(", ") + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + WebMock.stub_request(:get, uri).with do |request| + expect(request.headers['Accept']).to eql accept + end.to_return(body: "foo") + + reader_class.open(uri) do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here + end + end + + it "sets Accept header from symbol" do + uri = "http://example/foo" + sym = format_class.to_sym # Like RDF::NTriples::Format => :ntriples + accept = (format_class.accept_type + %w(*/*;q=0.1)).join(", ") + reader_mock = double("reader") + expect(reader_mock).to receive(:got_here) + WebMock.stub_request(:get, uri).with do |request| + expect(request.headers['Accept']).to eql accept + end.to_return(body: "foo") + expect(RDF::Reader).to receive(:for).with(sym).and_return(reader_class) + + RDF::Reader.open(uri, format: sym) do |r| + expect(r).to be_a(reader_class) + reader_mock.got_here + end + end end describe ".format" do - it "returns itself even if given explicit format" do + it "returns a format class if given no format" do + expect(reader_class.format).not_to be_nil + end + + it "returns nil if given a format" do other_format = reader_class == RDF::NTriples::Reader ? :nquads : :ntriples - expect(reader_class.for(other_format)).to eq reader_class + expect(reader_class.format(other_format)).to be_nil end end diff --git a/lib/rdf/spec/writer.rb b/lib/rdf/spec/writer.rb index 22dd777..d0182c5 100644 --- a/lib/rdf/spec/writer.rb +++ b/lib/rdf/spec/writer.rb @@ -11,6 +11,7 @@ end let(:writer_class) { writer.class } let(:reader_class) { writer_class.format.reader} + let(:format_class) { writer_class.format } describe ".each" do it "yields each writer" do @@ -63,56 +64,48 @@ end it "yields writer given file_name" do - writer_class.format.each do |f| - f.file_extensions.each_pair do |sym, content_type| - writer_mock = double("writer") - expect(writer_mock).to receive(:got_here) - expect(writer_class).to receive(:for).with(file_name: "#{@basename}.#{sym}").and_return(writer_class) - writer_class.open("#{@basename}.#{sym}") do |r| - expect(r).to be_a(RDF::Writer) - writer_mock.got_here - end - end - end - end - - it "yields writer given symbol" do - writer_class.format.each do |f| - sym = f.to_sym # Like RDF::NTriples::Format => :ntriples + format_class.file_extensions.each_pair do |sym, content_type| writer_mock = double("writer") expect(writer_mock).to receive(:got_here) - expect(writer_class).to receive(:for).with(sym).and_return(writer_class) - writer_class.open("#{@basename}.#{sym}", format: sym) do |r| + expect(writer_class).to receive(:for).with(file_name: "#{@basename}.#{sym}").and_return(writer_class) + writer_class.open("#{@basename}.#{sym}") do |r| expect(r).to be_a(RDF::Writer) writer_mock.got_here end end end + it "yields writer given symbol" do + sym = format_class.to_sym # Like RDF::NTriples::Format => :ntriples + writer_mock = double("writer") + expect(writer_mock).to receive(:got_here) + expect(writer_class).to receive(:for).with(sym).and_return(writer_class) + writer_class.open("#{@basename}.#{sym}", format: sym) do |r| + expect(r).to be_a(RDF::Writer) + writer_mock.got_here + end + end + it "yields writer given {file_name: file_name}" do - writer_class.format.each do |f| - f.file_extensions.each_pair do |sym, content_type| - writer_mock = double("writer") - expect(writer_mock).to receive(:got_here) - expect(writer_class).to receive(:for).with(file_name: "#{@basename}.#{sym}").and_return(writer_class) - writer_class.open("#{@basename}.#{sym}", file_name: "#{@basename}.#{sym}") do |r| - expect(r).to be_a(RDF::Writer) - writer_mock.got_here - end + format_class.file_extensions.each_pair do |sym, content_type| + writer_mock = double("writer") + expect(writer_mock).to receive(:got_here) + expect(writer_class).to receive(:for).with(file_name: "#{@basename}.#{sym}").and_return(writer_class) + writer_class.open("#{@basename}.#{sym}", file_name: "#{@basename}.#{sym}") do |r| + expect(r).to be_a(RDF::Writer) + writer_mock.got_here end end end it "yields writer given {content_type: 'a/b'}" do - writer_class.format.each do |f| - f.content_types.each_pair do |content_type, formats| - writer_mock = double("writer") - expect(writer_mock).to receive(:got_here) - expect(writer_class).to receive(:for).with(content_type: content_type, file_name: @basename).and_return(writer_class) - writer_class.open(@basename, content_type: content_type) do |r| - expect(r).to be_a(RDF::Writer) - writer_mock.got_here - end + format_class.content_types.each_pair do |content_type, formats| + writer_mock = double("writer") + expect(writer_mock).to receive(:got_here) + expect(writer_class).to receive(:for).with(content_type: content_type, file_name: @basename).and_return(writer_class) + writer_class.open(@basename, content_type: content_type) do |r| + expect(r).to be_a(RDF::Writer) + writer_mock.got_here end end end diff --git a/rdf-spec.gemspec b/rdf-spec.gemspec index 93551eb..6519f41 100755 --- a/rdf-spec.gemspec +++ b/rdf-spec.gemspec @@ -10,7 +10,6 @@ Gem::Specification.new do |gem| gem.license = 'Unlicense' gem.summary = 'RSpec extensions for RDF.rb.' gem.description = 'RDF.rb extension that provides RSpec matchers and shared examples for RDF objects.' - gem.rubyforge_project = 'rdf' gem.authors = ['Arto Bendiken', 'Ben Lavender', 'Gregg Kellogg'] gem.email = 'public-rdf-ruby@w3.org' @@ -27,11 +26,11 @@ Gem::Specification.new do |gem| gem.required_ruby_version = '>= 2.2.2' gem.requirements = [] - gem.add_runtime_dependency 'rdf', '~> 2.2' - gem.add_runtime_dependency 'rdf-isomorphic', '~> 2.0' - gem.add_runtime_dependency 'rspec', '~> 3.5' - gem.add_runtime_dependency 'rspec-its', '~> 1.0' - gem.add_runtime_dependency 'webmock', '~> 2.3' - gem.add_development_dependency 'yard' , '~> 0.8' + gem.add_runtime_dependency 'rdf', '~> 3.0' + gem.add_runtime_dependency 'rdf-isomorphic', '~> 3.0' + gem.add_runtime_dependency 'rspec', '~> 3.7' + gem.add_runtime_dependency 'rspec-its', '~> 1.2' + gem.add_runtime_dependency 'webmock', '~> 3.1' + gem.add_development_dependency 'yard' , '~> 0.9.12' gem.post_install_message = nil end diff --git a/spec/literal_spec.rb b/spec/literal_spec.rb index ae68552..559f025 100644 --- a/spec/literal_spec.rb +++ b/spec/literal_spec.rb @@ -15,8 +15,8 @@ %w(0 false) ] it_behaves_like 'RDF::Literal validation', RDF::XSD.boolean, - %w(true false tRuE FaLsE 1 0), - %w(foo 10) + %w(true false 1 0), + %w(foo 10) + ['true false', 'true foo', 'tRuE' 'FaLsE'] end describe RDF::Literal::Integer do