defmodule RDF.NTriples.DecoderTest do use ExUnit.Case, async: false doctest RDF.NTriples.Decoder alias RDF.{Graph, TestData} use RDF.Vocabulary.Namespace defvocab EX, base_uri: "http://example.org/#", terms: [], strict: false defvocab P, base_uri: "http://www.perceive.net/schemas/relationship/", terms: [], strict: false @w3c_ntriples_test_suite Path.join(TestData.dir, "N-TRIPLES-TESTS") test "an empty string is deserialized to an empty graph" do assert RDF.NTriples.Decoder.decode!("") == Graph.new assert RDF.NTriples.Decoder.decode!(" \n\r\r\n ") == Graph.new end test "decoding comments" do assert RDF.NTriples.Decoder.decode!("# just a comment") == Graph.new assert RDF.NTriples.Decoder.decode!(""" _:1 . # a comment """) == Graph.new({EX.S, EX.p, RDF.bnode("1")}) assert RDF.NTriples.Decoder.decode!(""" # a comment . """) == Graph.new({EX.S, EX.p, EX.O}) assert RDF.NTriples.Decoder.decode!(""" . # a comment """) == Graph.new({EX.S, EX.p, EX.O}) assert RDF.NTriples.Decoder.decode!(""" # Header line 1 # Header line 2 . # 1st comment . # 2nd comment # last comment """) == Graph.new([ {EX.S1, EX.p1, EX.O1}, {EX.S1, EX.p2, EX.O2}, ]) end test "empty lines" do assert RDF.NTriples.Decoder.decode!(""" . """) == Graph.new({EX.spiderman, P.enemyOf, EX.green_goblin}) assert RDF.NTriples.Decoder.decode!(""" . """) == Graph.new({EX.spiderman, P.enemyOf, EX.green_goblin}) assert RDF.NTriples.Decoder.decode!(""" . . """) == Graph.new([ {EX.S1, EX.p1, EX.O1}, {EX.S1, EX.p2, EX.O2}, ]) end test "decoding a single triple with uris" do assert RDF.NTriples.Decoder.decode!(""" . """) == Graph.new({EX.spiderman, P.enemyOf, EX.green_goblin}) end test "decoding a single triple with a blank node" do assert RDF.NTriples.Decoder.decode!(""" _:foo . """) == Graph.new({RDF.bnode("foo"), EX.p, EX.O}) assert RDF.NTriples.Decoder.decode!(""" _:1 . """) == Graph.new({EX.S, EX.p, RDF.bnode("1")}) assert RDF.NTriples.Decoder.decode!(""" _:foo _:bar . """) == Graph.new({RDF.bnode("foo"), EX.p, RDF.bnode("bar")}) end test "decoding a single triple with an untyped string literal" do assert RDF.NTriples.Decoder.decode!(""" "Peter Parker" . """) == Graph.new({EX.spiderman, P.realname, RDF.literal("Peter Parker")}) end test "decoding a single triple with a typed literal" do assert RDF.NTriples.Decoder.decode!(""" "42"^^ . """) == Graph.new({EX.spiderman, EX.p, RDF.literal(42)}) end test "decoding a single triple with a language tagged literal" do assert RDF.NTriples.Decoder.decode!(""" "foo"@en . """) == Graph.new({EX.S, EX.p, RDF.literal("foo", language: "en")}) end test "decoding multiple triples" do assert RDF.NTriples.Decoder.decode!(""" . . """) == Graph.new([ {EX.S1, EX.p1, EX.O1}, {EX.S1, EX.p2, EX.O2}, ]) assert RDF.NTriples.Decoder.decode!(""" . . . """) == Graph.new([ {EX.S1, EX.p1, EX.O1}, {EX.S1, EX.p2, EX.O2}, {EX.S2, EX.p3, EX.O3} ]) end describe "the official W3C RDF 1.1 N-Triples Test Suite" do # from https://www.w3.org/2013/N-TriplesTests/ ExUnit.Case.register_attribute __ENV__, :nt_test @w3c_ntriples_test_suite |> File.ls! |> Enum.filter(fn (file) -> Path.extname(file) == ".nt" end) |> Enum.each(fn (file) -> @nt_test file: Path.join(@w3c_ntriples_test_suite, file) if file |> String.contains?("-bad-") do test "Negative syntax test: #{file}", context do assert {:error, _} = RDF.NTriples.read_file(context.registered.nt_test[:file]) end else test "Positive syntax test: #{file}", context do assert {:ok, %RDF.Graph{}} = RDF.NTriples.read_file(context.registered.nt_test[:file]) end end end) end end