From f3a5b3e5e498b7f6d5b401e55287135a25c3deac Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 3 Nov 2015 13:06:03 -0800 Subject: [PATCH 01/13] Use `RDF::Formats.symbols` to define :n3 and :notation3 symbols for format, rather than an alias class. --- lib/rdf/n3/format.rb | 19 ++++--------------- spec/format_spec.rb | 10 ++-------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/lib/rdf/n3/format.rb b/lib/rdf/n3/format.rb index 53ab14f..3e0995b 100644 --- a/lib/rdf/n3/format.rb +++ b/lib/rdf/n3/format.rb @@ -22,21 +22,10 @@ class Format < RDF::Format reader { RDF::N3::Reader } writer { RDF::N3::Writer } - end - - # Alias for N3 format - # - # This allows the following: - # - # @example Obtaining an Notation3 format class - # RDF::Format.for(:ttl) #=> RDF::N3::Notation3 - # RDF::Format.for(:ttl).reader #=> RDF::N3::Reader - # RDF::Format.for(:ttl).writer #=> RDF::N3::Writer - class Notation3 < RDF::Format - content_type 'text/n3', extension: :n3 - content_encoding 'utf-8' - reader { RDF::N3::Reader } - writer { RDF::N3::Writer } + # Symbols which may be used to lookup this format + def self.symbols + [:n3, :notation3] + end end end diff --git a/spec/format_spec.rb b/spec/format_spec.rb index 38d41c1..a142891 100644 --- a/spec/format_spec.rb +++ b/spec/format_spec.rb @@ -10,6 +10,7 @@ describe ".for" do formats = [ :n3, + :notation3, 'etc/doap.n3', {file_name: 'etc/doap.n3'}, {file_extension: 'n3'}, @@ -28,7 +29,7 @@ default_prefix: ':a :b :c .', }.each do |sym, str| it "does not detect #{sym}" do - expect(described_class.for {str}).not_to eq described_class + expect(described_class.detect(str)).not_to eq described_class end end @@ -50,13 +51,6 @@ turtle: "@prefix foo: .\n foo:a foo:b .", n3: "@prefix foo: .\nfoo:bar = { } .", default_prefix: ':a :b :c .', - }.each do |sym, str| - it "does not detect #{sym}" do - expect(described_class.detect(str)).to be_falsey - end - end - - { nquads: " . ", rdfxml: '', jsonld: '{"@context" => "foo"}', From 8ce5d235a7107dffda2f04cd72ba0081daf2b862 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Fri, 13 Nov 2015 14:47:46 -0800 Subject: [PATCH 02/13] Use RDF::Util::Logger. --- lib/rdf/n3/reader.rb | 61 ++++++++--------- lib/rdf/n3/reader/parser.rb | 30 ++++----- lib/rdf/n3/writer.rb | 65 ++++++++---------- spec/matchers.rb | 84 +++++------------------- spec/reader_spec.rb | 127 ++++++++++++++++++------------------ spec/spec_helper.rb | 42 +----------- spec/suite_helper.rb | 6 +- spec/swap_spec.rb | 12 ++-- spec/writer_spec.rb | 4 +- 9 files changed, 157 insertions(+), 274 deletions(-) diff --git a/lib/rdf/n3/reader.rb b/lib/rdf/n3/reader.rb index 4bf648d..75ea747 100644 --- a/lib/rdf/n3/reader.rb +++ b/lib/rdf/n3/reader.rb @@ -16,6 +16,7 @@ module RDF::N3 class Reader < RDF::Reader format Format + include RDF::Util::Logger include Meta include Parser @@ -26,8 +27,6 @@ class Reader < RDF::Reader # # @param [IO, File, String] input # the input stream to read - # @option options [Array] :debug - # Array to place debug messages # @option options [#to_s] :base_uri (nil) # the base URI to use when resolving relative URIs (not supported by # all readers) @@ -65,12 +64,12 @@ def initialize(input = $stdin, options = {}, &block) @variables = {} # variable definitions along with defining formula if options[:base_uri] - add_debug("@uri") { base_uri.inspect} + log_debug("@uri") { base_uri.inspect} namespace(nil, uri("#{base_uri}#")) end - add_debug("validate") {validate?.inspect} - add_debug("canonicalize") {canonicalize?.inspect} - add_debug("intern") {intern?.inspect} + log_debug("validate") {validate?.inspect} + log_debug("canonicalize") {canonicalize?.inspect} + log_debug("intern") {intern?.inspect} if block_given? case block.arity @@ -96,6 +95,10 @@ def each_statement(&block) @callback = block parse(START.to_sym) + + if validate? && log_statistics[:error] + raise RDF::ReaderError, "Errors found during processing" + end end enum_for(:each_triple) end @@ -121,7 +124,7 @@ def each_triple(&block) # Start of production def onStart(prod) handler = "#{prod}Start".to_sym - add_debug("#{handler}(#{respond_to?(handler, true)})", prod) + log_debug("#{handler}(#{respond_to?(handler, true)})", prod) @productions << prod send(handler, prod) if respond_to?(handler, true) end @@ -130,7 +133,7 @@ def onStart(prod) def onFinish prod = @productions.pop() handler = "#{prod}Finish".to_sym - add_debug("#{handler}(#{respond_to?(handler, true)})") {"#{prod}: #{@prod_data.last.inspect}"} + log_debug("#{handler}(#{respond_to?(handler, true)})") {"#{prod}: #{@prod_data.last.inspect}"} send(handler) if respond_to?(handler, true) end @@ -139,7 +142,7 @@ def onToken(prod, tok) unless @productions.empty? parentProd = @productions.last handler = "#{parentProd}Token".to_sym - add_debug("#{handler}(#{respond_to?(handler, true)})") {"#{prod}, #{tok}: #{@prod_data.last.inspect}"} + log_debug("#{handler}(#{respond_to?(handler, true)})") {"#{prod}, #{tok}: #{@prod_data.last.inspect}"} send(handler, prod, tok) if respond_to?(handler, true) else error("Token has no parent production") @@ -186,9 +189,9 @@ def declarationFinish # This means that <#foo> can be written :foo and using @keywords one can reduce that to foo. namespace(nil, uri.match(/[\/\#]$/) ? base_uri : process_uri("#{uri}#")) - add_debug("declarationFinish[@base]") {"@base=#{base_uri}"} + log_debug("declarationFinish[@base]") {"@base=#{base_uri}"} when "@keywords" - add_debug("declarationFinish[@keywords]") {@keywords.inspect} + log_debug("declarationFinish[@keywords]") {@keywords.inspect} # Keywords are handled in tokenizer and maintained in @keywords array if (@keywords & N3_KEYWORDS) != @keywords error("Undefined keywords used: #{(@keywords - N3_KEYWORDS).to_sentence}") if validate? @@ -238,7 +241,7 @@ def expressionFinish # If we're in teh middle of a pathtail, append if @prod_data.last[:pathtail] && expression[:pathitem] && expression[:pathtail] path_list = [expression[:pathitem]] + expression[:pathtail] - add_debug("expressionFinish(pathtail)") {"set pathtail to #{path_list.inspect}"} + log_debug("expressionFinish(pathtail)") {"set pathtail to #{path_list.inspect}"} @prod_data.last[:pathtail] = path_list dir_list = [expression[:direction]] if expression[:direction] @@ -402,7 +405,7 @@ def simpleStatementFinish properties.each do |p| predicate = p[:verb] next unless predicate - add_debug("simpleStatementFinish(pred)") {predicate.to_s} + log_debug("simpleStatementFinish(pred)") {predicate.to_s} error(%(Illegal statment: "#{predicate}" missing object)) unless p.has_key?(:object) objects = Array(p[:object]) objects.each do |object| @@ -505,14 +508,14 @@ def verbFinish ################### def process_anonnode(anonnode) - add_debug("process_anonnode") {anonnode.inspect} + log_debug("process_anonnode") {anonnode.inspect} if anonnode[:propertylist] properties = anonnode[:propertylist] bnode = RDF::Node.new properties.each do |p| predicate = p[:verb] - add_debug("process_anonnode(verb)") {predicate.inspect} + log_debug("process_anonnode(verb)") {predicate.inspect} objects = Array(p[:object]) objects.each { |object| add_triple("anonnode", bnode, predicate, object) } end @@ -535,7 +538,7 @@ def process_anonnode(anonnode) # # Create triple and return property used for next iteration def process_path(expression) - add_debug("process_path") {expression.inspect} + log_debug("process_path") {expression.inspect} pathitem = expression[:pathitem] pathtail = expression[:pathtail] @@ -579,17 +582,17 @@ def process_qname(tok) end uri = if prefix(prefix) - add_debug('process_qname(ns)') {"#{prefix(prefix)}, #{name}"} + log_debug('process_qname(ns)') {"#{prefix(prefix)}, #{name}"} ns(prefix, name) elsif prefix == '_' - add_debug('process_qname(bnode)', name) + log_debug('process_qname(bnode)', name) bnode(name) else - add_debug('process_qname(default_ns)', name) + log_debug('process_qname(default_ns)', name) namespace(nil, uri("#{base_uri}#")) unless prefix(nil) ns(nil, name) end - add_debug('process_qname') {uri.inspect} + log_debug('process_qname') {uri.inspect} uri end @@ -619,18 +622,6 @@ def univar(label) RDF::Query::Variable.new(label.to_s) end - # Add debug event to debug array, if specified - # - # @param [any] node string for showing graph_name - # @param [String] message - # @yieldreturn [String] appended to message, to allow for lazy-evaulation of message - def add_debug(node, message = "") - return unless ::RDF::N3.debug? || @options[:debug] - message = message + yield if block_given? - puts "[#{@lineno},#{@pos}]#{' ' * @productions.length}#{node}: #{message}" if ::RDF::N3::debug? - @options[:debug] << "[#{@lineno},#{@pos}]#{' ' * @productions.length}#{node}: #{message}" if @options[:debug].is_a?(Array) - end - # add a statement, object can be literal or URI or bnode # # @param [any] node string for showing graph_name @@ -643,7 +634,7 @@ def add_triple(node, subject, predicate, object) graph_name_opts = @formulae.last ? {graph_name: @formulae.last} : {} statement = RDF::Statement.new(subject, predicate, object, graph_name_opts) - add_debug(node) {statement.to_s} + log_debug(node) {statement.to_s} @callback.call(statement) end @@ -652,7 +643,7 @@ def namespace(prefix, uri) if uri == '#' uri = prefix(nil).to_s + '#' end - add_debug("namespace") {"'#{prefix}' <#{uri}>"} + log_debug("namespace") {"'#{prefix}' <#{uri}>"} prefix(prefix, uri(uri)) end @@ -682,7 +673,7 @@ def uri(value, append = nil) def ns(prefix, suffix) base = prefix(prefix).to_s suffix = suffix.to_s.sub(/^\#/, "") if base.index("#") - add_debug("ns") {"base: '#{base}', suffix: '#{suffix}'"} + log_debug("ns") {"base: '#{base}', suffix: '#{suffix}'"} uri(base + suffix.to_s) end end diff --git a/lib/rdf/n3/reader/parser.rb b/lib/rdf/n3/reader/parser.rb index 1e57e08..7b4e5b4 100644 --- a/lib/rdf/n3/reader/parser.rb +++ b/lib/rdf/n3/reader/parser.rb @@ -9,7 +9,7 @@ module Parser NOT_NAME_CHARS = NOT_QNAME_CHARS + ":" def error(str) - raise RDF::ReaderError, "\n#{@line}\n#{'-' * @pos}^\nError on line #{@lineno} at offset #{@pos}: #{str}" + log_error(str, lineno: @lineno, exception: RDF::ReaderError) end def parse(prod) @@ -19,7 +19,7 @@ def parse(prod) if todo_stack.last[:terms].nil? todo_stack.last[:terms] = [] tok = self.token - #puts "parse tok: '#{tok}', prod #{todo_stack.last[:prod]}" + #log_debug("parse tok: '#{tok}'") {"prod #{todo_stack.last[:prod]}"} # Got an opened production onStart(abbr(todo_stack.last[:prod])) @@ -34,15 +34,15 @@ def parse(prod) expected = prod_branch.values.uniq.map {|u| u.map {|v| abbr(v).inspect}.join(",")} error("Found '#{tok}' when parsing a #{abbr(cur_prod)}. expected #{expected.join(' | ')}") end - #puts "sequence: #{sequence.inspect}" + #log_debug("sequence") {sequence.inspect} todo_stack.last[:terms] += sequence end - #puts "parse: #{todo_stack.last.inspect}" + #log_debug("parse") {todo_stack.last.inspect} while !todo_stack.last[:terms].to_a.empty? term = todo_stack.last[:terms].shift if term.is_a?(String) - puts "parse term(string): #{term}" if $verbose + log_debug("parse term(string)") {term.to_s} word = buffer[0, term.length] if word == term onToken(term, word) @@ -59,28 +59,28 @@ def parse(prod) string = '"""' consume(3) next_line = buffer - #puts "ml-str(start): #{next_line.dump}" if $verbose + #log_debug("ml-str(start)") {next_line.dump} until md = R_MLSTRING.match(next_line) begin string += next_line next_line = readline - rescue EOFError => e + rescue EOFError error("EOF reached searching for end of multi-line comment") end end string += md[0].to_s consume(md[0].to_s.length) onToken('string', string) - #puts "ml-str now #{buffer.dump}" + #log_debug("ml-str now") {buffer.dump} else md = regexp.match(buffer) error("Token(#{abbr(term)}) '#{buffer[0, 10]}...' should match #{regexp}") unless md - puts "parse term(#{abbr(term)}:regexp): #{term}, #{regexp}.match('#{buffer[0, 10]}...') => '#{md.inspect}'" if $verbose + log_debug("parse") {"term(#{abbr(term)}:regexp): #{term}, #{regexp}.match('#{buffer[0, 10]}...') => '#{md.inspect}'"} onToken(abbr(term), md.to_s) consume(md[0].length) end else - puts "parse term(push): #{term}" if $verbose + log_debug("parse term(push)") {term} todo_stack << {prod: term, terms: nil} pushed = true break @@ -104,7 +104,7 @@ def token unless @memo.has_key?(@pos) tok = self.get_token @memo[@pos] = tok - puts "token: '#{tok}'('#{buffer[0, 10]}...')" if buffer && $verbose + log_debug("token") {"'#{tok}'('#{buffer[0, 10]}...')"} if buffer end @memo[@pos] end @@ -158,7 +158,7 @@ def whitespace while buffer && md = R_WHITESPACE.match(buffer) return unless md[0].length > 0 consume(md[0].length) - #puts "ws: '#{md[0]}', pos=#{@pos}" + #log_debug("ws") {"'#{md[0]}', pos=#{@pos}"} end end @@ -166,10 +166,10 @@ def readline @line = @input.readline @lineno += 1 @line.force_encoding(Encoding::UTF_8) - puts "readline[#{@lineno}]: #{@line.dump}" if $verbose + log_debug("readline[#{@lineno}]") {@line.dump} @pos = 0 @line - rescue EOFError => e + rescue EOFError @line, @pos = nil, 0 end @@ -183,7 +183,7 @@ def consume(n) @memo = {} @pos += n readline while @line && @line.length <= @pos - #puts "consume[#{n}]: '#{buffer}'" if $verbose + #log_debug("consume[#{n}]") {buffer} end def abbr(prodURI) diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index 9f9ca1e..0444824 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -50,6 +50,7 @@ module RDF::N3 # @author [Gregg Kellogg](http://greggkellogg.net/) class Writer < RDF::Writer format RDF::N3::Format + include RDF::Util::Logger QNAME = Meta::REGEXPS[:"http://www.w3.org/2000/10/swap/grammar/n3#qname"] # @return [Graph] Graph of statements serialized @@ -136,11 +137,10 @@ def write_triple(subject, predicate, object) def write_epilogue @max_depth = @options[:max_depth] || 3 @base_uri = RDF::URI(@options[:base_uri]) - @debug = @options[:debug] self.reset - add_debug {"\nserialize: graph: #{@graph.size}"} + log_debug {"\nserialize: graph: #{@graph.size}"} preprocess start_document @@ -165,7 +165,7 @@ def get_qname(resource) return nil end - add_debug {"get_qname(#{resource}), std?}"} + log_debug {"get_qname(#{resource}), std?}"} qname = case when @uri_to_qname.has_key?(uri) return @uri_to_qname[uri] @@ -173,13 +173,13 @@ def get_qname(resource) # Use a defined prefix prefix = @uri_to_prefix[u] prefix(prefix, u) unless u.to_s.empty? # Define for output - add_debug {"get_qname: add prefix #{prefix.inspect} => #{u}"} + log_debug {"get_qname: add prefix #{prefix.inspect} => #{u}"} uri.sub(u.to_s, "#{prefix}:") when @options[:standard_prefixes] && vocab = RDF::Vocabulary.each.to_a.detect {|v| uri.index(v.to_uri.to_s) == 0} prefix = vocab.__name__.to_s.split('::').last.downcase @uri_to_prefix[vocab.to_uri.to_s] = prefix prefix(prefix, vocab.to_uri) # Define for output - add_debug {"get_qname: add standard prefix #{prefix.inspect} => #{vocab.to_uri}"} + log_debug {"get_qname: add standard prefix #{prefix.inspect} => #{vocab.to_uri}"} uri.sub(vocab.to_uri.to_s, "#{prefix}:") else nil @@ -214,7 +214,7 @@ def sort_properties(properties) prop_list << prop.to_s end - add_debug {"sort_properties: #{prop_list.join(', ')}"} + log_debug {"sort_properties: #{prop_list.join(', ')}"} prop_list end @@ -252,7 +252,7 @@ def format_literal(literal, options = {}) # @return [String] def format_uri(uri, options = {}) md = relativize(uri) - add_debug {"relativize(#{uri.inspect}) => #{md.inspect}"} if md != uri.to_s + log_debug {"relativize(#{uri.inspect}) => #{md.inspect}"} if md != uri.to_s md != uri.to_s ? "<#{md}>" : (get_qname(uri) || "<#{uri}>") end @@ -273,7 +273,7 @@ def start_document @output.write("#{indent}@base <#{base_uri}> .\n") unless base_uri.to_s.empty? - add_debug {"start_document: #{prefixes.inspect}"} + log_debug {"start_document: #{prefixes.inspect}"} prefixes.keys.sort_by(&:to_s).each do |prefix| @output.write("#{indent}@prefix #{prefix}: <#{prefixes[prefix]}> .\n") end @@ -309,17 +309,17 @@ def order_subjects subjects << base_uri seen[base_uri] = true end - add_debug {"subjects1: #{subjects.inspect}"} + log_debug {"subjects1: #{subjects.inspect}"} # Add distinguished classes top_classes.each do |class_uri| graph.query(predicate: RDF.type, object: class_uri).map {|st| st.subject}.sort.uniq.each do |subject| - add_debug {"order_subjects: #{subject.inspect}"} + log_debug {"order_subjects: #{subject.inspect}"} subjects << subject seen[subject] = true end end - add_debug {"subjects2: #{subjects.inspect}"} + log_debug {"subjects2: #{subjects.inspect}"} # Sort subjects by resources over bnodes, ref_counts and the subject URI itself recursable = @subjects.keys. @@ -327,9 +327,9 @@ def order_subjects map {|r| [r.node? ? 1 : 0, ref_count(r), r]}. sort - add_debug {"subjects3: #{subjects.inspect}"} + log_debug {"subjects3: #{subjects.inspect}"} subjects += recursable.map{|r| r.last} - add_debug {"subjects4: #{subjects.inspect}"} + log_debug {"subjects4: #{subjects.inspect}"} subjects end @@ -350,7 +350,7 @@ def preprocess # prefixes. # @param [Statement] statement def preprocess_statement(statement) - #add_debug {"preprocess: #{statement.inspect}"} + #log_debug {"preprocess: #{statement.inspect}"} references = ref_count(statement.object) + 1 @references[statement.object] = references @subjects[statement.subject] = true @@ -405,30 +405,19 @@ def quoted(string) private - # Add debug event to debug array, if specified - # - # @param [String] message - # @yieldreturn [String] appended to message, to allow for lazy-evaulation of message - def add_debug(message = "") - return unless ::RDF::N3.debug? || @debug - message = message + yield if block_given? - STDERR.puts message if ::RDF::N3::debug? - @debug << message if @debug.is_a?(Array) - end - # Checks if l is a valid RDF list, i.e. no nodes have other properties. def is_valid_list(l) - #add_debug {"is_valid_list: #{l.inspect}"} + #log_debug {"is_valid_list: #{l.inspect}"} return (l.node? && RDF::List.new(l, @graph).valid?) || l == RDF.nil end def do_list(l) list = RDF::List.new(l, @graph) - add_debug {"do_list: #{list.inspect}"} + log_debug {"do_list: #{list.inspect}"} position = :subject list.each_statement do |st| next unless st.predicate == RDF.first - add_debug {" list this: #{st.subject} first: #{st.object}[#{position}]"} + log_debug {" list this: #{st.subject} first: #{st.object}[#{position}]"} path(st.object, position) subject_done(st.subject) position = :object @@ -437,7 +426,7 @@ def do_list(l) def p_list(node, position) return false if !is_valid_list(node) - #add_debug {"p_list: #{node.inspect}, #{position}"} + #log_debug {"p_list: #{node.inspect}, #{position}"} @output.write(position == :subject ? "(" : " (") @depth += 2 @@ -455,7 +444,7 @@ def p_squared?(node, position) def p_squared(node, position) return false unless p_squared?(node, position) - #add_debug {"p_squared: #{node.inspect}, #{position}"} + #log_debug {"p_squared: #{node.inspect}, #{position}"} subject_done(node) @output.write(position == :subject ? '[' : ' [') @depth += 2 @@ -467,13 +456,13 @@ def p_squared(node, position) end def p_default(node, position) - #add_debug {"p_default: #{node.inspect}, #{position}"} + #log_debug {"p_default: #{node.inspect}, #{position}"} l = (position == :subject ? "" : " ") + format_term(node, options) @output.write(l) end def path(node, position) - add_debug do + log_debug do "path: #{node.inspect}, " + "pos: #{position}, " + "[]: #{is_valid_list(node)}, " + @@ -484,7 +473,7 @@ def path(node, position) end def verb(node) - add_debug {"verb: #{node.inspect}"} + log_debug {"verb: #{node.inspect}"} if node == RDF.type @output.write(" a") else @@ -493,7 +482,7 @@ def verb(node) end def object_list(objects) - add_debug {"object_list: #{objects.inspect}"} + log_debug {"object_list: #{objects.inspect}"} return if objects.empty? objects.each_with_index do |obj, i| @@ -510,7 +499,7 @@ def predicate_list(subject) end prop_list = sort_properties(properties) - [RDF.first.to_s, RDF.rest.to_s] - add_debug {"predicate_list: #{prop_list.inspect}"} + log_debug {"predicate_list: #{prop_list.inspect}"} return if prop_list.empty? prop_list.each_with_index do |prop, i| @@ -519,7 +508,7 @@ def predicate_list(subject) verb(prop[0, 2] == "_:" ? RDF::Node.intern(prop.split(':').last) : RDF::URI.intern(prop)) object_list(properties[prop]) rescue Addressable::URI::InvalidURIError => e - add_debug {"Predicate #{prop.inspect} is an invalid URI: #{e.message}"} + log_debug {"Predicate #{prop.inspect} is an invalid URI: #{e.message}"} end end end @@ -531,7 +520,7 @@ def s_squared?(subject) def s_squared(subject) return false unless s_squared?(subject) - add_debug {"s_squared: #{subject.inspect}"} + log_debug {"s_squared: #{subject.inspect}"} @output.write("\n#{indent} [") @depth += 1 predicate_list(subject) @@ -549,7 +538,7 @@ def s_default(subject) end def statement(subject) - add_debug {"statement: #{subject.inspect}, s2?: #{s_squared?(subject)}"} + log_debug {"statement: #{subject.inspect}, s2?: #{s_squared?(subject)}"} subject_done(subject) s_squared(subject) || s_default(subject) @output.write("\n") diff --git a/spec/matchers.rb b/spec/matchers.rb index 6cab59e..34edec2 100644 --- a/spec/matchers.rb +++ b/spec/matchers.rb @@ -1,22 +1,23 @@ require 'rdf/isomorphic' -def normalize(graph) - case graph - when RDF::Enumerable then graph - when IO, StringIO - RDF::Repository.new.load(graph, base_uri: @info.about) - else - # Figure out which parser to use - g = RDF::Repository.new - reader_class = RDF::Reader.for(detect_format(graph)) - reader_class.new(graph, base_uri: @info.about).each {|s| g << s} - g - end -end - +# Don't use be_equivalent_graph from rdf/spec because of odd N3 semantics Info = Struct.new(:about, :information, :trace, :inputDocument, :outputDocument, :format) RSpec::Matchers.define :be_equivalent_graph do |expected, info| + def normalize(graph) + case graph + when RDF::Enumerable then graph + when IO, StringIO + RDF::Repository.new.load(graph, base_uri: @info.about) + else + # Figure out which parser to use + g = RDF::Repository.new + reader_class = RDF::Reader.for(detect_format(graph)) + reader_class.new(graph, base_uri: @info.about).each {|s| g << s} + g + end + end + match do |actual| @info = if info.respond_to?(:about) info @@ -53,58 +54,3 @@ def normalize(graph) (@info.trace ? "\nDebug:\n#{@info.trace}" : "") end end - -module Matchers - class MatchRE - Info = Struct.new(:about, :information, :trace, :inputDocument, :outputDocument) - def initialize(expected, info) - @info = if info.respond_to?(:about) - info - elsif info.is_a?(Hash) - identifier = info[:identifier] || info[:about] - trace = info[:trace] - trace = trace.join("\n") if trace.is_a?(Array) - Info.new(identifier, info[:information] || "", trace, info[:inputDocument], info[:outputDocument]) - else - Info.new(info, info.to_s) - end - @expected = expected - end - - def matches?(actual) - @actual = actual - @actual.to_s.match(@expected) - end - - def failure_message_for_should - info = @info.respond_to?(:information) ? @info.information : @info.inspect - "Match failed" - "\n#{info + "\n" unless info.empty?}" + - (@info.inputDocument ? "Input file: #{@info.inputDocument}\n" : "") + - (@info.outputDocument ? "Output file: #{@info.outputDocument}\n" : "") + - "Expression: #{@expected}\n" + - "Unsorted Results:\n#{@actual}" + - (@info.trace ? "\nDebug:\n#{@info.trace}" : "") - end - def negative_failure_message - "Match succeeded\n" - end - end - - def match_re(expected, info = nil) - MatchRE.new(expected, info) - end -end - -RSpec::Matchers.define :produce do |expected, info| - match do |actual| - actual == expected - end - - failure_message do |actual| - "Expected: #{[Array, Hash].include?(expected.class) ? expected.to_json(JSON_STATE) : expected.inspect}\n" + - "Actual : #{[Array, Hash].include?(actual.class) ? actual.to_json(JSON_STATE) : actual.inspect}\n" + - #(expected.is_a?(Hash) && actual.is_a?(Hash) ? "Diff: #{expected.diff(actual).to_json(JSON_STATE)}\n" : "") + - "Processing results:\n#{info.join("\n")}" - end -end diff --git a/spec/reader_spec.rb b/spec/reader_spec.rb index ac73414..bf0842c 100644 --- a/spec/reader_spec.rb +++ b/spec/reader_spec.rb @@ -7,6 +7,7 @@ let!(:doap) {File.expand_path("../../etc/doap.n3", __FILE__)} let!(:doap_nt) {File.expand_path("../../etc/doap.nt", __FILE__)} let!(:doap_count) {File.open(doap_nt).each_line.to_a.length} + let(:logger) {RDF::Spec.logger} it_behaves_like 'an RDF::Reader' do let(:reader) {RDF::N3::Reader.new(reader_input)} @@ -262,8 +263,7 @@ }.each_pair do |name, statement| specify "test #{name}" do graph = parse([statement].flatten.first) - expect(graph.size).to eq 1 - expect(graph.to_ntriples.chomp).to eq [statement].flatten.last.gsub(/\s+/, " ").strip + expect(graph).to be_equivalent_graph([statement].flatten.last, about: "http://a/b", logger: logger) end end @@ -294,7 +294,7 @@ %(<#D%C3%BCrst> a "URI percent ^encoded as C3, BC".) => %( "URI percent ^encoded as C3, BC" .), }.each_pair do |n3, nt| it "for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -305,7 +305,7 @@ %(:alice :resumé "Alice's normalized resumé".) => ' "Alice\'s normalized resumé" .', }.each_pair do |n3, nt| it "for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -314,7 +314,7 @@ #%(:a :related :ひらがな .) => %( .), }.each_pair do |n3, nt| it "for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end end @@ -351,7 +351,7 @@ nt = %( . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should use <#> as a prefix and as a triple node" do @@ -359,31 +359,31 @@ nt = %( . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate rdf:type for 'a'" do n3 = %(@prefix a: . a:b a .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate rdf:type for '@a'" do n3 = %(@prefix a: . a:b @a .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate inverse predicate for 'is xxx of'" do n3 = %("value" is :prop of :b . :b :prop "value" .) nt = %( "value" .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate inverse predicate for '@is xxx @of'" do n3 = %("value" @is :prop @of :b . :b :prop "value" .) nt = %( "value" .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate inverse predicate for 'is xxx of' with object list" do @@ -392,37 +392,37 @@ "value" . "value" . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate predicate for 'has xxx'" do n3 = %(@prefix a: . a:b has :pred a:c .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should generate predicate for '@has xxx'" do n3 = %(@prefix a: . a:b @has :pred a:c .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create log:implies predicate for '=>'" do n3 = %(@prefix a: . _:a => a:something .) nt = %(_:a .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create log:implies inverse predicate for '<='" do n3 = %(@prefix a: . _:a <= a:something .) nt = %( _:a .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create owl:sameAs predicate for '='" do n3 = %(@prefix a: . _:a = a:something .) nt = %(_:a .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end { @@ -438,20 +438,20 @@ %(:a :b 1.0E1) => %( "1.0e1"^^ .), }.each_pair do |n3, nt| it "should create typed literal for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end it "should accept empty localname" do n3 = %(: : : .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should accept prefix with empty local name" do n3 = %(@prefix foo: . foo: foo: foo: .) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "substitutes variable for URI with @forAll" do @@ -503,7 +503,7 @@ nt = %( . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should not append # for http://foo/bar/" do @@ -511,7 +511,7 @@ nt = %( . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should not append # for http://foo/bar#" do @@ -519,7 +519,7 @@ nt = %( . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should set absolute base" do @@ -528,7 +528,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should set absolute base (trailing /)" do @@ -537,7 +537,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should set absolute base (trailing #)" do @@ -546,7 +546,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should set relative base" do @@ -566,7 +566,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "returns defined prefixes" do @@ -622,7 +622,7 @@ %(:c :a t) => %( .), }.each_pair do |n3, nt| it "should use default_ns for '#{n3}'" do - expect(parse("@keywords . #{n3}", base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse("@keywords . #{n3}", base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -635,7 +635,7 @@ %(@keywords has. :a has :b :c.) => %( .), } .each_pair do |n3, nt| it "should use keyword for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -658,7 +658,7 @@ . _:a . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should allow a prefix to be redefined" do @@ -673,7 +673,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should process sequential @base declarations (swap base.n3)" do @@ -687,7 +687,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -696,39 +696,39 @@ n3 = %(@prefix a: . _:a a:p a:v .) nt = %(_:bnode0 .) g = parse(n3, base_uri: "http://a/b") - expect(g).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(g).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create BNode for [] as subject" do n3 = %(@prefix a: . [] a:p a:v .) nt = %(_:bnode0 .) g = parse(n3, base_uri: "http://a/b") - expect(g).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(g).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create BNode for [] as predicate" do n3 = %(@prefix a: . a:s [] a:o .) nt = %( _:bnode0 .) g = parse(n3, base_uri: "http://a/b") - expect(g).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(g).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create BNode for [] as object" do n3 = %(@prefix a: . a:s a:p [] .) nt = %( _:bnode0 .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create BNode for [] as statement" do n3 = %([:a :b] .) nt = %(_:bnode0 .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create statements with BNode subjects using [ pref obj]" do n3 = %(@prefix a: . [ a:p a:v ] .) nt = %(_:bnode0 .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create BNode as a single object" do @@ -738,7 +738,7 @@ _:bnode0 "2" . _:bnode0 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create a shared BNode" do @@ -757,7 +757,7 @@ _:bnode0 "2" . _:a :pred _:bnode0 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create nested BNodes" do @@ -774,20 +774,20 @@ _:bnode1 "v4" . _:bnode1 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end describe "from paths" do it "should create bnode for path x!p" do n3 = %(:x2!:y2 :p2 "3" .) nt = %(:x2 :y2 _:bnode0 . _:bnode0 :p2 "3" .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should create bnode for path x^p" do n3 = %(:x2^:y2 :p2 "3" .) nt = %(_:bnode0 :y2 :x2 . _:bnode0 :p2 "3" .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should decode :joe!fam:mother!loc:office!loc:zip as Joe's mother's office's zipcode" do @@ -802,7 +802,7 @@ _:bnode0 _:bnode1 . _:bnode1 _:bnode2 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should decode :joe!fam:mother^fam:mother Anyone whose mother is Joe's mother." do @@ -816,7 +816,7 @@ :joe _:bnode0 . _:bnode1 _:bnode0 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should decode path with property list." do @@ -831,7 +831,7 @@ _:bnode1 :q2 "4" . _:bnode1 :q2 "5" . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should decode path as object(1)" do @@ -840,7 +840,7 @@ :a :b _:bnode . _:bnode :c "lit" . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should decode path as object(2)" do @@ -850,7 +850,7 @@ _:bnode0 _:bnode1 . :r :p _:bnode1 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end end @@ -920,7 +920,7 @@ it "should create 2 statements for simple list" do n3 = %(:a :b :c, :d) nt = %( . .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -938,7 +938,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -947,7 +947,7 @@ n3 = %(@prefix :. :empty :set ().) nt = %( .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should parse list with single element" do @@ -957,7 +957,7 @@ _:bnode0 . _:bnode0 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should parse list with multiple elements" do @@ -971,7 +971,7 @@ _:bnode2 . _:bnode0 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should parse unattached lists" do @@ -990,13 +990,13 @@ _:bnode2 "3" . _:bnode2 . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should add property to nil list" do n3 = %(@prefix a: . () a:prop "nilProp" .) nt = %( "nilProp" .) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end it "should parse with compound items" do @@ -1068,7 +1068,7 @@ . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -1089,7 +1089,7 @@ _:g2160128180 . . ) - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -1108,7 +1108,7 @@ nt = %( . ) - expect(@graph).to be_equivalent_graph(nt, about: "http://test/", trace: @debug) + expect(@graph).to be_equivalent_graph(nt, about: "http://test/", logger: logger) end it "should have default subject" do @@ -1154,7 +1154,7 @@ # it "returns subject #{result} given #{input}" do # n3 = %(#{input} a :b) # nt = %(#{result} .) -# parse(n3, base_uri: "http://a/b", canonicalize: true).should be_equivalent_graph(nt, about: "http://a/b", trace: @debug) +# parse(n3, base_uri: "http://a/b", canonicalize: true).should be_equivalent_graph(nt, about: "http://a/b", logger: logger) # end # end @@ -1167,7 +1167,7 @@ it "returns object #{result} given #{input}" do n3 = %(@prefix xsd: . :a :b #{input} .) nt = %( #{result} .) - expect(parse(n3, base_uri: "http://a/b", canonicalize: true)).to be_equivalent_graph(nt, about: "http://a/b", trace: @debug) + expect(parse(n3, base_uri: "http://a/b", canonicalize: true)).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end end @@ -1206,14 +1206,13 @@ expect(graph).to be_equivalent_graph(sampledoc, about: "http://www.w3.org/2000/10/rdf-tests/rdfcore/amp-in-url/Manifest.rdf", - trace: @debug + logger: logger ) end def parse(input, options = {}) - @debug = ([] unless RUBY_ENGINE == "rbx") options = { - debug: @debug, + logger: logger, validate: false, canonicalize: false, }.merge(options) @@ -1231,6 +1230,6 @@ def test_file(filepath) nt_string = File.read(filepath.sub('.n3', '.nt')) expect(@graph).to be_equivalent_graph(nt_string, about: "file:#{filepath}", - trace: @debug) + logger: logger) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d4fc786..fb11ee6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,67 +3,27 @@ require "bundler/setup" require 'rspec' -require 'matchers' require 'bigdecimal' # XXX Remove Me require 'rdf/n3' require 'rdf/ntriples' require 'rdf/spec' require 'rdf/spec/matchers' +require 'matchers' require 'rdf/isomorphic' require 'yaml' # XXX should be in open-uri/cached require 'open-uri/cached' -include Matchers - # Create and maintain a cache of downloaded URIs URI_CACHE = File.expand_path(File.join(File.dirname(__FILE__), "uri-cache")) Dir.mkdir(URI_CACHE) unless File.directory?(URI_CACHE) OpenURI::Cache.class_eval { @cache_path = URI_CACHE } -module RDF - module Isomorphic - alias_method :==, :isomorphic_with? - end - class Graph - def to_ntriples - RDF::Writer.for(:ntriples).buffer do |writer| - self.each_statement do |statement| - writer << statement - end - end - end - def dump - b = [] - self.each_statement do |statement| - b << statement.to_triple.inspect - end - b.join("\n") - end - end -end - ::RSpec.configure do |c| c.filter_run focus: true c.run_all_when_everything_filtered = true c.exclusion_filter = { ruby: lambda { |version| !(RUBY_VERSION.to_s =~ /^#{version.to_s}/) }, } - c.include(Matchers) - c.include(RDF::Spec::Matchers) -end - -# Serialize graph and replace bnodes with predictable versions, return as sorted array -def normalize_bnodes(graph, anon = "a") - anon_ctx = {} - # Find and replace all BNodes within graph string - g_str = graph.to_ntriples - anon_entries = g_str.scan(/_:g\d+/).sort.uniq - anon_entries.each do |a| - anon_ctx[a] = "_:#{anon}" - anon = anon.succ - end - - g_str.gsub(/_:g\d+/) { |bn| anon_ctx[bn] }.split("\n").sort end # Heuristically detect the input stream diff --git a/spec/suite_helper.rb b/spec/suite_helper.rb index d0a7c6c..9a8d799 100644 --- a/spec/suite_helper.rb +++ b/spec/suite_helper.rb @@ -22,7 +22,7 @@ def self.open(file) end end end - attr_accessor :debug + attr_accessor :logger def base inputDocument @@ -57,10 +57,6 @@ def syntax? !outputDocument end - def trace - debug.join("\n") if debug - end - def inspect super.sub('>', "\n" + " positive?: #{positive_test?.inspect}\n" + diff --git a/spec/swap_spec.rb b/spec/swap_spec.rb index 949fd94..079b9af 100644 --- a/spec/swap_spec.rb +++ b/spec/swap_spec.rb @@ -24,13 +24,15 @@ when *%w(n3_10008 n3_10013) pending("Isomorphic compare issue") else - t.debug = [t.inspect, "source:", t.input.read] + t.logger = RDF::Spec.logger + t.logger.info t.inspect + t.logger.info "source:\n#{t.input}" reader = RDF::N3::Reader.new(t.input, base_uri: t.base, canonicalize: false, validate: true, - debug: (t.debug unless RUBY_ENGINE == "rbx")) + logger: t.logger) graph = RDF::Repository.new @@ -38,7 +40,7 @@ begin graph << reader rescue Exception => e - expect(e.message).to produce("Not exception #{e.inspect}", t.debug) + expect(e.message).to produce("Not exception #{e.inspect}", t.logger) end if t.evaluate? @@ -46,7 +48,7 @@ format = detect_format(t.outputDocument) RDF::Repository.load(t.outputDocument, format: format, base_uri: t.inputDocument) rescue Exception => e - expect(e.message).to produce("Not exception #{e.inspect}", t.debug) + expect(e.message).to produce("Not exception #{e.inspect}", t.logger) end expect(graph).to be_equivalent_graph(output_graph, t) @@ -56,7 +58,7 @@ else expect { graph << reader - graph.dump(:ntriples).should produce("not this", t.debug) + graph.dump(:ntriples).should produce("not this", t.logger) }.to raise_error(RDF::ReaderError) end end diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index 9069f4f..084136c 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -3,6 +3,7 @@ require 'rdf/spec/writer' describe RDF::N3::Writer do + let(:logger) {RDF::Spec.logger} it_behaves_like 'an RDF::Writer' do let(:writer) {RDF::N3::Writer.new(StringIO.new)} end @@ -402,8 +403,7 @@ def parse(input, options = {}) def serialize(ntstr, base = nil, regexps = [], options = {}) prefixes = options[:prefixes] || {} g = parse(ntstr, base_uri: base, prefixes: prefixes) - @debug = [] - result = RDF::N3::Writer.buffer(options.merge(debug: @debug, base_uri: base, prefixes: prefixes)) do |writer| + result = RDF::N3::Writer.buffer(options.merge(logger: logger, base_uri: base, prefixes: prefixes)) do |writer| writer << g end if $verbose From 8bbf2acce84a4b1c24552cfbf2cf66f0b58848aa Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Fri, 13 Nov 2015 15:19:30 -0800 Subject: [PATCH 03/13] Handle some problematic JRuby cases. --- lib/rdf/n3.rb | 3 --- lib/rdf/n3/reader.rb | 1 + lib/rdf/n3/reader/parser.rb | 1 + lib/rdf/n3/writer.rb | 1 + script/console | 10 ------- script/parse | 22 +++++++++------ script/tc | 53 ------------------------------------- script/yard-to-rubyforge | 2 -- spec/matchers.rb | 45 ++++++++++++++++--------------- spec/reader_spec.rb | 12 ++++----- spec/writer_spec.rb | 1 + 11 files changed, 47 insertions(+), 104 deletions(-) delete mode 100755 script/console delete mode 100755 script/tc delete mode 100755 script/yard-to-rubyforge diff --git a/lib/rdf/n3.rb b/lib/rdf/n3.rb index ccbb1d0..8199c2f 100644 --- a/lib/rdf/n3.rb +++ b/lib/rdf/n3.rb @@ -28,8 +28,5 @@ module N3 autoload :Reader, 'rdf/n3/reader' autoload :VERSION, 'rdf/n3/version' autoload :Writer, 'rdf/n3/writer' - - def self.debug?; @debug; end - def self.debug=(value); @debug = value; end end end \ No newline at end of file diff --git a/lib/rdf/n3/reader.rb b/lib/rdf/n3/reader.rb index 75ea747..0e369e0 100644 --- a/lib/rdf/n3/reader.rb +++ b/lib/rdf/n3/reader.rb @@ -1,3 +1,4 @@ +# coding: utf-8 module RDF::N3 ## # A Notation-3/Turtle parser in Ruby diff --git a/lib/rdf/n3/reader/parser.rb b/lib/rdf/n3/reader/parser.rb index 7b4e5b4..bdf3133 100644 --- a/lib/rdf/n3/reader/parser.rb +++ b/lib/rdf/n3/reader/parser.rb @@ -1,3 +1,4 @@ +# coding: utf-8 # Simple parser to go through productions without attempting evaluation module RDF::N3 module Parser diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index 0444824..6a1a35b 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -1,3 +1,4 @@ +# coding: utf-8 module RDF::N3 ## # A Turtle serialiser in Ruby diff --git a/script/console b/script/console deleted file mode 100755 index 7719c44..0000000 --- a/script/console +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env ruby -# File: script/console -irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' - -libs = " -r irb/completion" -RDF = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "rdf", "lib")) -libs << " -I #{RDF}" if File.directory?(RDF) -libs << " -r #{File.join(File.expand_path(File.dirname(__FILE__)), "..", "lib", "rdf", "n3.rb")}" -puts "Loading rdf-n3 gem" -exec "#{irb} #{libs} --simple-prompt" diff --git a/script/parse b/script/parse index d9268d9..182a07a 100755 --- a/script/parse +++ b/script/parse @@ -1,10 +1,12 @@ #!/usr/bin/env ruby require 'rubygems' $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib'))) +require "bundler/setup" +require 'logger' require 'rdf/n3' require 'rdf/ntriples' -require 'rdf/rdfxml' rescue nil -require 'rdf/rdfa' rescue nil +require 'rdf/rdfxml' +require 'rdf/rdfa' require 'getoptlong' require 'open-uri' @@ -60,9 +62,13 @@ rescue Exception => e raise e end +logger = Logger.new(STDERR) +logger.level = Logger::WARN +logger.formatter = lambda {|severity, datetime, progname, msg| "#{severity}: #{msg}\n"} + parser_options = { base_uri: "http://example.com", - progress: false, + logger: logger, validate: false, } @@ -79,7 +85,6 @@ opts = GetoptLong.new( ["--errors", GetoptLong::NO_ARGUMENT], ["--execute", "-e", GetoptLong::REQUIRED_ARGUMENT], ["--canonicalize", GetoptLong::NO_ARGUMENT], - ["--freebase", GetoptLong::NO_ARGUMENT], ["--format", GetoptLong::REQUIRED_ARGUMENT], ["--input-format", GetoptLong::REQUIRED_ARGUMENT], ["--output", "-o", GetoptLong::REQUIRED_ARGUMENT], @@ -92,17 +97,18 @@ opts = GetoptLong.new( ) opts.each do |opt, arg| case opt - when '--dbg' then parser_options[:debug] = ::RDF::N3::debug = true + when '--dbg' then logger.level = Logger::DEBUG when '--canonicalize' then parser_options[:canonicalize] = true when '--errors' then options[:errors] = true when '--execute' then input = arg when '--format' then options[:output_format] = arg.to_sym - when '--freebase' then parser_options[:freebase] = true when '--input-format' then options[:input_format] = arg.to_sym when '--output' then options[:output] = File.open(arg, "w") when '--profile' then options[:profile] = true - when '--progress' then parser_options[:debug] ||= 2 - when '--quiet' then options[:quiet] = options[:quiet].to_i + 1 + when '--progress' then logger.level = Logger::INFO + when '--quiet' + options[:quiet] = true + logger.level = Logger::FATAL when '--uri' then parser_options[:base_uri] = arg when '--validate' then parser_options[:debug] ||= 1 when '--verbose' then $verbose = true diff --git a/script/tc b/script/tc deleted file mode 100755 index b67cc72..0000000 --- a/script/tc +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env ruby -s -require 'rubygems' -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib'))) -require 'rdf/n3' -require File.expand_path(File.join(File.dirname(__FILE__), "..", 'spec', 'rdfa_helper')) -require 'getoptlong' - -def run_tc(tc) - puts "run #{tc.name}" - puts RDF::Writer.for($output_format.to_sym).buffer { |writer| - RDF::N3::Reader.new(tc.input, base_uri: tc.about, strict: $strict).each do |statement| - writer << statement - end - } -end - -$verbose = false -$output_format = :ntriples -$strict = false -suite = "turtle" -opts = GetoptLong.new( - ["--debug", GetoptLong::NO_ARGUMENT], - ["--verbose", GetoptLong::NO_ARGUMENT], - ["--quiet", GetoptLong::NO_ARGUMENT], - ["--suite", GetoptLong::OPTIONAL_ARGUMENT], - ["--strict", GetoptLong::NO_ARGUMENT], - ["--format", GetoptLong::REQUIRED_ARGUMENT] -) -opts.each do |opt, arg| - case opt - when '--verbose' then $verbose = true - when '--quiet' then $quiet = true - when '--debug' then ::RDF::N3::debug = true - when '--format' then $output_format = arg - when '--suite' then suite = arg - when '--strict' then $strict = true - end -end - -# Test URI and directory for different suites -TEST_PARAMS = { - "rdfxml" => [RDFCORE_TEST, RDFCORE_DIR], - "cwm" => [CWM_TEST, SWAP_DIR], - "swap" => [SWAP_TEST, SWAP_DIR], - "turtle" => [TURTLE_TEST, TURTLE_DIR], - "turtlebad" => [TURTLE_BAD_TEST, TURTLE_DIR], -} -test_cases = RdfHelper::TestCase.test_cases(*TEST_PARAMS[suite]) - -test_cases = test_cases.detect do |tc| - next unless ARGV.empty? || ARGV.any? {|n| tc.name.match(/#{n}/)} - run_tc(tc) -end diff --git a/script/yard-to-rubyforge b/script/yard-to-rubyforge deleted file mode 100755 index a6c4532..0000000 --- a/script/yard-to-rubyforge +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env sh -rsync -azv -e "ssh -i /Users/gregg/.ssh/id_dsa" doc/yard/ gkellogg@rubyforge.org:/var/www/gforge-projects/rdf/n3/ diff --git a/spec/matchers.rb b/spec/matchers.rb index 34edec2..9e76b71 100644 --- a/spec/matchers.rb +++ b/spec/matchers.rb @@ -1,35 +1,32 @@ require 'rdf/isomorphic' # Don't use be_equivalent_graph from rdf/spec because of odd N3 semantics -Info = Struct.new(:about, :information, :trace, :inputDocument, :outputDocument, :format) +Info = Struct.new(:about, :logger, :inputDocument, :outputDocument, :format) RSpec::Matchers.define :be_equivalent_graph do |expected, info| - def normalize(graph) - case graph - when RDF::Enumerable then graph - when IO, StringIO - RDF::Repository.new.load(graph, base_uri: @info.about) - else - # Figure out which parser to use - g = RDF::Repository.new - reader_class = RDF::Reader.for(detect_format(graph)) - reader_class.new(graph, base_uri: @info.about).each {|s| g << s} - g + match do |actual| + def normalize(graph) + case graph + when RDF::Enumerable then graph + when IO, StringIO + RDF::Repository.new.load(graph, base_uri: @info.about) + else + # Figure out which parser to use + g = RDF::Repository.new + reader_class = RDF::Reader.for(detect_format(graph)) + reader_class.new(graph, base_uri: @info.about).each {|s| g << s} + g + end end - end - match do |actual| @info = if info.respond_to?(:about) info + elsif info.is_a?(Logger) + Info.new("", info) elsif info.is_a?(Hash) - identifier = expected.is_a?(RDF::Graph) ? expected.graph_name : info[:about] - trace = info[:trace] - trace = trace.join("\n") if trace.is_a?(Array) - i = Info.new(identifier, "0000", trace) - i.format = info[:format] - i + Info.new(info[:about], info[:logger]) else - Info.new(expected.is_a?(RDF::Graph) ? expected.graph_name : info, "0000", info.to_s) + Info.new(expected.is_a?(RDF::Graph) ? expected.graph_name : info, info.to_s) end @info.format ||= :n3 @expected = normalize(expected) @@ -38,6 +35,10 @@ def normalize(graph) end failure_message do |actual| + trace = case @info.logger + when Logger then @info.logger.to_s + when Array then @info.logger.join("\n") + end info = @info.respond_to?(:about) ? @info.about : @info.inspect if @expected.is_a?(RDF::Enumerable) && @actual.size != @expected.size "Graph entry count differs:\nexpected: #{@expected.size}\nactual: #{@actual.size}" @@ -51,6 +52,6 @@ def normalize(graph) (@info.outputDocument ? "Output file: #{@info.outputDocument}\n" : "") + "Expected:\n#{@expected.dump(@info.format, standard_prefixes: true)}" + "Results:\n#{@actual.dump(@info.format, standard_prefixes: true)}" + - (@info.trace ? "\nDebug:\n#{@info.trace}" : "") + (trace ? "\nDebug:\n#{trace}" : "") end end diff --git a/spec/reader_spec.rb b/spec/reader_spec.rb index bf0842c..2a064e1 100644 --- a/spec/reader_spec.rb +++ b/spec/reader_spec.rb @@ -155,13 +155,13 @@ end { - 'Dürst' => ':a :b "Dürst" .', - "é" => ':a :b "é" .', - "€" => ':a :b "€" .', + 'Dürst' => ' "Dürst" .', + "é" => ' "é" .', + "€" => ' "€" .', "resumé" => ':a :resume "resumé" .', }.each_pair do |contents, triple| specify "test #{triple}" do - graph = parse(triple, base_uri: "http://a/b") + graph = parse(triple, base_uri: "http://a/b", logger: false) statement = graph.statements.first expect(graph.size).to eq 1 expect(statement.object.value).to eq contents @@ -305,7 +305,7 @@ %(:alice :resumé "Alice's normalized resumé".) => ' "Alice\'s normalized resumé" .', }.each_pair do |n3, nt| it "for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) + expect(parse(n3, base_uri: "http://a/b", logger: false)).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end @@ -314,7 +314,7 @@ #%(:a :related :ひらがな .) => %( .), }.each_pair do |n3, nt| it "for '#{n3}'" do - expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) + expect(parse(n3, base_uri: "http://a/b", logger: false)).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) end end end diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index 084136c..cc701dc 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -1,3 +1,4 @@ +# coding: utf-8 $:.unshift "." require File.join(File.dirname(__FILE__), 'spec_helper') require 'rdf/spec/writer' From 3195cf962d37cdc827f455ed589b1050f49a88cd Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 21 Nov 2015 10:54:20 -0800 Subject: [PATCH 04/13] Remove `#write_graph` and `#write_statement`. Work done now using `#write_triple`. Other writer updates for new expectations. --- lib/rdf/n3/writer.rb | 21 +++------------------ spec/writer_spec.rb | 13 ++++++++----- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index 6a1a35b..77210b9 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -101,23 +101,6 @@ def initialize(output = $stdout, options = {}, &block) end end - ## - # Write whole graph - # - # @param [Graph] graph - # @return [void] - def write_graph(graph) - @graph = graph - end - - ## - # Addes a statement to be serialized - # @param [RDF::Statement] statement - # @return [void] - def write_statement(statement) - @graph.insert(statement) - end - ## # Addes a triple to be serialized # @param [RDF::Resource] subject @@ -127,7 +110,7 @@ def write_statement(statement) # @raise [NotImplementedError] unless implemented in subclass # @abstract def write_triple(subject, predicate, object) - @graph.insert(Statement.new(subject, predicate, object)) + @graph.insert(RDF::Statement(subject, predicate, object)) end ## @@ -151,6 +134,8 @@ def write_epilogue statement(subject) end end + + super end # Return a QName for the URI, or nil. Adds namespace of QName to defined prefixes diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index cc701dc..0e7f282 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -5,6 +5,9 @@ describe RDF::N3::Writer do let(:logger) {RDF::Spec.logger} + + after(:each) {|example| puts logger.to_s if example.exception} + it_behaves_like 'an RDF::Writer' do let(:writer) {RDF::N3::Writer.new(StringIO.new)} end @@ -309,7 +312,7 @@ [%q(false), /false ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do - ttl = %(@prefix xsd: . :a :b #{l} .) + ttl = %(@prefix : . @prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, @@ -328,7 +331,7 @@ [%q(10), /10 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do - ttl = %(@prefix xsd: . :a :b #{l} .) + ttl = %(@prefix : . @prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, @@ -344,7 +347,7 @@ [%q("10"^^xsd:int), /"10"\^\^xsd:int ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do - ttl = %(@prefix xsd: . :a :b #{l} .) + ttl = %(@prefix : . @prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, @@ -363,7 +366,7 @@ [%q(10.02), /10.02 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do - ttl = %(@prefix xsd: . :a :b #{l} .) + ttl = %(@prefix : . @prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, @@ -382,7 +385,7 @@ [%q(10.02e1), /1.002e2 ./], ].each do |(l,r)| it "uses token for #{l.inspect}" do - ttl = %(@prefix xsd: . :a :b #{l} .) + ttl = %(@prefix : . @prefix xsd: . :a :b #{l} .) serialize(ttl, nil, [ %r(@prefix xsd: \.), r, From 465c31b11d1758c9fed75aa5fe1b9a9548469956 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 21 Nov 2015 11:36:13 -0800 Subject: [PATCH 05/13] Correct some encoding errors for JRuby. Allow CI errors on JRuby, not 2.2. --- .travis.yml | 2 +- lib/rdf/n3/reader/meta.rb | 1 + lib/rdf/n3/reader/parser.rb | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 106f203..a0a5563 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ cache: bundler sudo: false matrix: allow_failures: - - rvm: 2.2 + - rvm: jruby diff --git a/lib/rdf/n3/reader/meta.rb b/lib/rdf/n3/reader/meta.rb index 7f769a9..54e2d9e 100644 --- a/lib/rdf/n3/reader/meta.rb +++ b/lib/rdf/n3/reader/meta.rb @@ -1,3 +1,4 @@ +# coding: utf-8 # This file is automatically generated by script/build_meta # Branch and Regexp tables derived from http://www.w3.org/2000/10/swap/grammar/n3-selectors.n3 module RDF::N3::Meta diff --git a/lib/rdf/n3/reader/parser.rb b/lib/rdf/n3/reader/parser.rb index bdf3133..14fc805 100644 --- a/lib/rdf/n3/reader/parser.rb +++ b/lib/rdf/n3/reader/parser.rb @@ -76,7 +76,7 @@ def parse(prod) else md = regexp.match(buffer) error("Token(#{abbr(term)}) '#{buffer[0, 10]}...' should match #{regexp}") unless md - log_debug("parse") {"term(#{abbr(term)}:regexp): #{term}, #{regexp}.match('#{buffer[0, 10]}...') => '#{md.inspect}'"} + log_debug("parse") {"term(#{abbr(term)}:regexp): #{term}, #{regexp}.match('#{buffer[0, 10]}...') => '#{md.inspect.force_encoding(Encoding::UTF_8)}'"} onToken(abbr(term), md.to_s) consume(md[0].length) end From 22bb3816731787b1cd6bd4a72aae241abac32b6a Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 2 Jan 2016 12:20:10 -0800 Subject: [PATCH 06/13] Finish keyword-arguments --- .travis.yml | 8 ++++---- Gemfile | 2 +- README.md | 4 ++-- lib/rdf/n3/reader.rb | 2 +- lib/rdf/n3/writer.rb | 4 ++-- rdf-n3.gemspec | 2 +- script/build_meta | 2 +- spec/reader_spec.rb | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index a0a5563..6c618ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,14 +4,14 @@ script: "bundle exec rspec spec" env: - CI=true rvm: - - 1.9.3 - 2.0 - 2.1 - - 2.2 - - jruby + - 2.2.4 + - jruby-9.0.4.0 - rbx-2 cache: bundler sudo: false matrix: allow_failures: - - rvm: jruby + - rvm: jruby-9.0.4.0 + - rvm: rbx-2 diff --git a/Gemfile b/Gemfile index 50f5779..08ed9ec 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ end group :debug do gem "wirble" - gem "debugger", platforms: [:mri_19, :mri_20] + gem "byebug", platform: :mri end platforms :rbx do diff --git a/README.md b/README.md index cd273e8..27b3c53 100755 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ results in: h = RDF::Query::Variable.new(<#h>) g = RDF::Node.new() - RDF::Statement.new(f, <#loves>, h) + RDF::Statement(f, <#loves>, h) ## Implementation Notes The parser is driven through a rules table contained in lib/rdf/n3/reader/meta.rb. This includes @@ -84,7 +84,7 @@ http://www.w3.org/2000/10/swap/grammar/n3.n3 (along with bnf-rules.n3) using cwm * Create equivalent to `--think` to iterate on solutions. ## Dependencies -* [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.1) +* [RDF.rb](http://rubygems.org/gems/rdf) (>= 2.0) ## Documentation Full documentation available on [RubyDoc.info](http://rubydoc.info/github/ruby-rdf/rdf-n3/frames) diff --git a/lib/rdf/n3/reader.rb b/lib/rdf/n3/reader.rb index 0e369e0..f5e4d1a 100644 --- a/lib/rdf/n3/reader.rb +++ b/lib/rdf/n3/reader.rb @@ -634,7 +634,7 @@ def univar(label) def add_triple(node, subject, predicate, object) graph_name_opts = @formulae.last ? {graph_name: @formulae.last} : {} - statement = RDF::Statement.new(subject, predicate, object, graph_name_opts) + statement = RDF::Statement(subject, predicate, object, graph_name_opts) log_debug(node) {statement.to_s} @callback.call(statement) end diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index 77210b9..d960240 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -394,11 +394,11 @@ def quoted(string) # Checks if l is a valid RDF list, i.e. no nodes have other properties. def is_valid_list(l) #log_debug {"is_valid_list: #{l.inspect}"} - return (l.node? && RDF::List.new(l, @graph).valid?) || l == RDF.nil + return (l.node? && RDF::List.new(subject: l, graph: @graph).valid?) || l == RDF.nil end def do_list(l) - list = RDF::List.new(l, @graph) + list = RDF::List.new(subject: l, graph: @graph) log_debug {"do_list: #{list.inspect}"} position = :subject list.each_statement do |st| diff --git a/rdf-n3.gemspec b/rdf-n3.gemspec index 7747467..9267651 100755 --- a/rdf-n3.gemspec +++ b/rdf-n3.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |gem| gem.require_paths = %w(lib) gem.has_rdoc = false - gem.required_ruby_version = '>= 1.9.3' + gem.required_ruby_version = '>= 2.0.0' gem.requirements = [] gem.add_dependency 'rdf', '~> 1.99' diff --git a/script/build_meta b/script/build_meta index a42e4c1..ebc9711 100755 --- a/script/build_meta +++ b/script/build_meta @@ -103,7 +103,7 @@ class PredictiveParser graph.query(subject: lhs, predicate: BNF.branch) do |statement| branch = statement.object sequence = graph.first_object(subject: statement.object, predicate: BNF.sequence) - option = RDF::List.new(sequence, graph).to_a + option = RDF::List.new(subject: sequence, graph: graph).to_a progress(" option: #{option}") option.each do |part| diff --git a/spec/reader_spec.rb b/spec/reader_spec.rb index 2a064e1..641792b 100644 --- a/spec/reader_spec.rb +++ b/spec/reader_spec.rb @@ -1029,7 +1029,7 @@ expect(g.subjects.to_a.length).to eq 8 n = g.first_object(subject: RDF::URI.new("http://foo/a#a"), predicate: RDF::URI.new("http://foo/a#p")) expect(n).to be_node - seq = RDF::List.new(n, g) + seq = RDF::List.new(subject: n, graph: g) expect(seq.to_a.length).to eq 4 expect(seq.first).to be_node expect(seq.second).to eq RDF::URI.new("http://resource1") From fb7e88a7843f296dc10969159a73a90a51b3bba7 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sat, 2 Jan 2016 15:59:11 -0800 Subject: [PATCH 07/13] Update required ruby version >= 2.0. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 27b3c53..765a8a0 100755 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ RDF::N3 parses [Notation-3][N3], [Turtle][Turtle] and [N-Triples][N-Triples] int Install with `gem install rdf-n3` ## Limitations -* Full support of Unicode input requires Ruby version 1.9 or greater. +* Full support of Unicode input requires Ruby version 2.0 or greater. * Support for Variables in Formulae dependent on underlying repository. Existential variables are quantified to RDF::Node instances, Universals to RDF::Query::Variable, with the URI of the variable target used as the variable name. * No support for N3 Reification. If there were, it would be through a :reify option to the reader. From c188acd3c01d516dbf323ea55c51d26c9772e1f8 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 4 Jan 2016 15:32:23 -0800 Subject: [PATCH 08/13] Add writer options. --- lib/rdf/n3/writer.rb | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index d960240..1622199 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -58,7 +58,25 @@ class Writer < RDF::Writer attr_accessor :graph # @return [URI] Base URI used for relativizing URIs attr_accessor :base_uri - + + ## + # Options suitable for automatic Reader provisioning. + # @return [Array] + def self.options + super + [ + RDF::CLI::Option.new( + symbol: :max_depth, + datatype: Integer, + on: ["--max-depth"], + description: "Maximum depth for recursively defining resources, defaults to 3.") {|arg| arg.to_i}, + RDF::CLI::Option.new( + symbol: :default_namespace, + datatype: RDF::URI, + on: ["--default-namespace URI", :REQUIRED], + description: "URI to use as default namespace, same as prefixes.") {|arg| RDF::URI(arg)}, + ] + end + ## # Initializes the Turtle writer instance. # From 45dac9b895b2fea0faf18a605fd2e8176d393779 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 4 Jan 2016 16:15:09 -0800 Subject: [PATCH 09/13] Doc update. --- lib/rdf/n3/writer.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rdf/n3/writer.rb b/lib/rdf/n3/writer.rb index 1622199..0225cce 100644 --- a/lib/rdf/n3/writer.rb +++ b/lib/rdf/n3/writer.rb @@ -60,8 +60,8 @@ class Writer < RDF::Writer attr_accessor :base_uri ## - # Options suitable for automatic Reader provisioning. - # @return [Array] + # N3 Writer options + # @see http://www.rubydoc.info/github/ruby-rdf/rdf/RDF/Writer#options-class_method def self.options super + [ RDF::CLI::Option.new( From 5c60672664ef335005bfb5483eeb8b98af0ad3a4 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 18 Jan 2016 10:42:59 -0800 Subject: [PATCH 10/13] Updates to ensure that compared literal values are the same as those input, rather than depending on literal equality. --- .travis.yml | 1 + spec/reader_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6c618ac..eea2813 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ rvm: - 2.0 - 2.1 - 2.2.4 + - 2.3.0 - jruby-9.0.4.0 - rbx-2 cache: bundler diff --git a/spec/reader_spec.rb b/spec/reader_spec.rb index 641792b..c7176e1 100644 --- a/spec/reader_spec.rb +++ b/spec/reader_spec.rb @@ -268,9 +268,9 @@ end it "should allow mixed-case language" do - n3doc = %(:x2 :p "xyz"@EN .) + n3doc = %(:x2 :p "xyz"@en .) statement = parse(n3doc).statements.first - expect(statement.object.to_ntriples).to eq %("xyz"@EN) + expect(statement.object.to_ntriples).to eq %("xyz"@en) end it "should create typed literals" do @@ -435,7 +435,7 @@ %(:a :b 1.0e1) => %( "1.0e1"^^ .), %(:a :b 1.0e-1) => %( "1.0e-1"^^ .), %(:a :b 1.0e+1) => %( "1.0e+1"^^ .), - %(:a :b 1.0E1) => %( "1.0e1"^^ .), + %(:a :b 1.0E1) => %( "1.0E1"^^ .), }.each_pair do |n3, nt| it "should create typed literal for '#{n3}'" do expect(parse(n3, base_uri: "http://a/b")).to be_equivalent_graph(nt, about: "http://a/b", logger: logger) From 5a4b7f8ef6cd4a46413532506847b84e31fc7aa8 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 19 Jan 2016 11:38:45 -0800 Subject: [PATCH 11/13] Remove some order dependencies in writer tests. --- spec/writer_spec.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/writer_spec.rb b/spec/writer_spec.rb index 0e7f282..8ccc644 100644 --- a/spec/writer_spec.rb +++ b/spec/writer_spec.rb @@ -111,8 +111,7 @@ input = %(@prefix : . :b :c :d, :e .) serialize(input, nil, [%r(^@prefix : \.$), - %r(^:b :c :d,$), - %r(^\s+:e \.$)], + %r(^:b :c :[de],\s+:[de] \.$)m], prefixes: { "" => "http://xmlns.com/foaf/0.1/"} ) end @@ -121,8 +120,7 @@ input = %(@prefix : . :b :c :d; :e :f .) serialize(input, nil, [%r(^@prefix : \.$), - %r(^:b :c :d;$), - %r(^\s+:e :f \.$)], + %r(^:b :[ce] :[df];\s+:[ce] :[df] \.$)], prefixes: { "" => "http://xmlns.com/foaf/0.1/"} ) end @@ -232,7 +230,7 @@ it "should generate list anon" do input = %(@prefix : . :twoAnons = ([a :mother] [a :father]) .) serialize(input, nil, - [%r(^:twoAnons (<.*sameAs>|owl:sameAs) \(\[\s*a :mother\] \[\s*a :father\]\) \.$)], + [%r(^:twoAnons (<.*sameAs>|owl:sameAs) \(\[\s*a :(mother|father)\] \[\s*a :(mother|father)\]\) \.$)], prefixes: { "" => "http://xmlns.com/foaf/0.1/"} ) end From 6bf20dd821c41c51c576b7eeb197670552eb96e3 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Sun, 31 Jan 2016 14:24:37 -0800 Subject: [PATCH 12/13] Change gemspec dependencies to '>= 1.99', '< 3' in prep for 2.0.0.beta release. --- rdf-n3.gemspec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rdf-n3.gemspec b/rdf-n3.gemspec index 9267651..805c07e 100755 --- a/rdf-n3.gemspec +++ b/rdf-n3.gemspec @@ -23,14 +23,14 @@ Gem::Specification.new do |gem| gem.required_ruby_version = '>= 2.0.0' gem.requirements = [] - gem.add_dependency 'rdf', '~> 1.99' + gem.add_dependency 'rdf', '>= 1.99', '< 3' gem.add_development_dependency 'open-uri-cached', '~> 0.0', '>= 0.0.5' - gem.add_development_dependency 'json-ld', '~> 1.99' + gem.add_development_dependency 'json-ld', '>= 1.99', '< 3' gem.add_development_dependency 'rspec', '~> 3.2' gem.add_development_dependency 'rspec-its', '~> 1.0' - gem.add_development_dependency 'rdf-spec', '~> 1.99' - gem.add_development_dependency 'rdf-rdfxml', '~> 1.1' - gem.add_development_dependency 'rdf-isomorphic', '~> 1.1' + gem.add_development_dependency 'rdf-spec', '>= 1.99', '< 3' + gem.add_development_dependency 'rdf-rdfxml', '>= 1.99', '< 3' + gem.add_development_dependency 'rdf-isomorphic', '>= 1.99', '< 3' gem.add_development_dependency 'yard' , '~> 0.8' gem.post_install_message = nil From b0cb6435f1666fa72b2c3e610691d20b8bf5bf5b Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 2 Feb 2016 16:16:26 -0800 Subject: [PATCH 13/13] Set version to 2.0.0.beta1 and change gemspec dependencies to '>= 2.0.0.beta', '< 3' until 2.0.0 is released. --- Gemfile | 2 -- VERSION | 2 +- rdf-n3.gemspec | 7 +++---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 08ed9ec..1b9777d 100644 --- a/Gemfile +++ b/Gemfile @@ -7,8 +7,6 @@ gem "rdf", git: "git://github.com/ruby-rdf/rdf.git", branch: "develop group :development do gem "rdf-spec", git: "git://github.com/ruby-rdf/rdf-spec.git", branch: "develop" gem "rdf-isomorphic", git: "git://github.com/ruby-rdf/rdf-isomorphic.git", branch: "develop" - gem "rdf-rdfa", git: "git://github.com/ruby-rdf/rdf-rdfa.git", branch: "develop" - gem "rdf-rdfxml", git: "git://github.com/ruby-rdf/rdf-rdfxml.git", branch: "develop" gem "rdf-xsd", git: "git://github.com/ruby-rdf/rdf-xsd.git", branch: "develop" gem "json-ld", git: "git://github.com/ruby-rdf/json-ld.git", branch: "develop" end diff --git a/VERSION b/VERSION index 9eb2e1f..fcd0328 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.99.0 +2.0.0.beta1 diff --git a/rdf-n3.gemspec b/rdf-n3.gemspec index 805c07e..bf4a611 100755 --- a/rdf-n3.gemspec +++ b/rdf-n3.gemspec @@ -23,14 +23,13 @@ Gem::Specification.new do |gem| gem.required_ruby_version = '>= 2.0.0' gem.requirements = [] - gem.add_dependency 'rdf', '>= 1.99', '< 3' + gem.add_dependency 'rdf', '>= 2.0.0.beta', '< 3' gem.add_development_dependency 'open-uri-cached', '~> 0.0', '>= 0.0.5' gem.add_development_dependency 'json-ld', '>= 1.99', '< 3' gem.add_development_dependency 'rspec', '~> 3.2' gem.add_development_dependency 'rspec-its', '~> 1.0' - gem.add_development_dependency 'rdf-spec', '>= 1.99', '< 3' - gem.add_development_dependency 'rdf-rdfxml', '>= 1.99', '< 3' - gem.add_development_dependency 'rdf-isomorphic', '>= 1.99', '< 3' + gem.add_development_dependency 'rdf-spec', '>= 2.0.0.beta', '< 3' + gem.add_development_dependency 'rdf-isomorphic', '>= 2.0.0.beta', '< 3' gem.add_development_dependency 'yard' , '~> 0.8' gem.post_install_message = nil