From c172cd18eaa9c73e32de3692786e8e395d4cd020 Mon Sep 17 00:00:00 2001 From: Marco De Salvo Date: Mon, 27 May 2024 17:18:30 +0200 Subject: [PATCH] Added more tests and fixed typos in tests --- RDFSharp.Test/Model/RDFGraphTest.cs | 4 +- .../Store/Engines/RDFMemoryStoreTest.cs | 132 +++++++++++++++++- RDFSharp/Model/RDFGraph.cs | 3 +- RDFSharp/Store/Engines/RDFMemoryStore.cs | 66 +++++++-- 4 files changed, 186 insertions(+), 19 deletions(-) diff --git a/RDFSharp.Test/Model/RDFGraphTest.cs b/RDFSharp.Test/Model/RDFGraphTest.cs index 40b3830c..abb5f9f0 100644 --- a/RDFSharp.Test/Model/RDFGraphTest.cs +++ b/RDFSharp.Test/Model/RDFGraphTest.cs @@ -1584,8 +1584,8 @@ public void ShouldImportFromFileWithEnabledDatatypeDiscovery(string fileExtensio .AddTriple(triple2) .AddDatatype(new RDFDatatype(new Uri($"ex:mydt{(int)format}"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ new RDFPatternFacet("^ex$") ])); - graph1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFGraphTest_ShouldImportFromFile{fileExtension}")); - RDFGraph graph2 = RDFGraph.FromFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFGraphTest_ShouldImportFromFile{fileExtension}"), true); + graph1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFGraphTest_ShouldImportFromFile{fileExtension}WithEnabledDatatypeDiscovery")); + RDFGraph graph2 = RDFGraph.FromFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFGraphTest_ShouldImportFromFile{fileExtension}WithEnabledDatatypeDiscovery"), true); Assert.IsNotNull(graph2); Assert.IsTrue(graph2.TriplesCount == 9); diff --git a/RDFSharp.Test/Store/Engines/RDFMemoryStoreTest.cs b/RDFSharp.Test/Store/Engines/RDFMemoryStoreTest.cs index 9757f3c2..32f41a59 100644 --- a/RDFSharp.Test/Store/Engines/RDFMemoryStoreTest.cs +++ b/RDFSharp.Test/Store/Engines/RDFMemoryStoreTest.cs @@ -1141,6 +1141,31 @@ public void ShouldImportFromFile(string fileExtension, RDFStoreEnums.RDFFormats Assert.IsTrue(store2.Equals(store1)); } + [DataTestMethod] + [DataRow(".nq", RDFStoreEnums.RDFFormats.NQuads)] + [DataRow(".trix", RDFStoreEnums.RDFFormats.TriX)] + [DataRow(".trig", RDFStoreEnums.RDFFormats.TriG)] + public void ShouldImportFromFileWithEnabledDatatypeDiscovery(string fileExtension, RDFStoreEnums.RDFFormats format) + { + RDFMemoryStore store1 = new RDFMemoryStore(); + RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFPlainLiteral("lit", "en-US")); + RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFResource("http://ex/obj/")); + store1.AddQuadruple(quadruple1) + .AddQuadruple(quadruple2) + .MergeGraph(new RDFGraph() + .AddDatatype(new RDFDatatype(new Uri($"ex:mydtPP{(int)format}"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ + new RDFPatternFacet("^ex$") ]))); + store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFile{fileExtension}WithEnabledDatatypeDiscovery")); + RDFMemoryStore store2 = RDFMemoryStore.FromFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFile{fileExtension}WithEnabledDatatypeDiscovery"), true); + + Assert.IsNotNull(store2); + Assert.IsTrue(store2.QuadruplesCount == 9); + Assert.IsTrue(store2.Equals(store1)); + //Test that automatic datatype discovery happened successfully + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtPP{(int)format}").TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING); + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtPP{(int)format}").Facets.Single() is RDFPatternFacet fct && fct.Pattern == "^ex$"); + } + [DataTestMethod] [DataRow(".nq", RDFStoreEnums.RDFFormats.NQuads)] [DataRow(".trix", RDFStoreEnums.RDFFormats.TriX)] @@ -1174,14 +1199,39 @@ public async Task ShouldImportFromFileAsync(string fileExtension, RDFStoreEnums. RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFPlainLiteral("lit", "en-US")); RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFResource("http://ex/obj/")); store1.AddQuadruple(quadruple1).AddQuadruple(quadruple2); - store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFile{fileExtension}")); - RDFMemoryStore store2 = await RDFMemoryStore.FromFileAsync(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFile{fileExtension}")); + store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFileAsync{fileExtension}")); + RDFMemoryStore store2 = await RDFMemoryStore.FromFileAsync(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFileAsync{fileExtension}")); Assert.IsNotNull(store2); Assert.IsTrue(store2.QuadruplesCount == 2); Assert.IsTrue(store2.Equals(store1)); } + [DataTestMethod] + [DataRow(".nq", RDFStoreEnums.RDFFormats.NQuads)] + [DataRow(".trix", RDFStoreEnums.RDFFormats.TriX)] + [DataRow(".trig", RDFStoreEnums.RDFFormats.TriG)] + public async Task ShouldImportFromFileAsyncWithEnabledDatatypeDiscovery(string fileExtension, RDFStoreEnums.RDFFormats format) + { + RDFMemoryStore store1 = new RDFMemoryStore(); + RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFPlainLiteral("lit", "en-US")); + RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFResource("http://ex/obj/")); + store1.AddQuadruple(quadruple1) + .AddQuadruple(quadruple2) + .MergeGraph(new RDFGraph() + .AddDatatype(new RDFDatatype(new Uri($"ex:mydtP{(int)format}"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ + new RDFPatternFacet("^ex$") ]))); + store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFileAsync{fileExtension}WithEnabledDatatypeDiscovery")); + RDFMemoryStore store2 = await RDFMemoryStore.FromFileAsync(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportFromFileAsync{fileExtension}WithEnabledDatatypeDiscovery"), true); + + Assert.IsNotNull(store2); + Assert.IsTrue(store2.QuadruplesCount == 9); + Assert.IsTrue(store2.Equals(store1)); + //Test that automatic datatype discovery happened successfully + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtP{(int)format}").TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING); + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtP{(int)format}").Facets.Single() is RDFPatternFacet fct && fct.Pattern == "^ex$"); + } + [DataTestMethod] [DataRow(".nq", RDFStoreEnums.RDFFormats.NQuads)] [DataRow(".trix", RDFStoreEnums.RDFFormats.TriX)] @@ -1189,8 +1239,8 @@ public async Task ShouldImportFromFileAsync(string fileExtension, RDFStoreEnums. public async Task ShouldImportEmptyFromFileAsync(string fileExtension, RDFStoreEnums.RDFFormats format) { RDFMemoryStore store1 = new RDFMemoryStore(); - store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportEmptyFromFile{fileExtension}")); - RDFMemoryStore store2 = await RDFMemoryStore.FromFileAsync(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportEmptyFromFile{fileExtension}")); + store1.ToFile(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportEmptyFromFileAsync{fileExtension}")); + RDFMemoryStore store2 = await RDFMemoryStore.FromFileAsync(format, Path.Combine(Environment.CurrentDirectory, $"RDFMemoryStoreTest_ShouldImportEmptyFromFileAsync{fileExtension}")); Assert.IsNotNull(store2); Assert.IsTrue(store2.QuadruplesCount == 0); @@ -1224,6 +1274,32 @@ public void ShouldImportFromStream(RDFStoreEnums.RDFFormats format) Assert.IsTrue(store2.Equals(store1)); } + [DataTestMethod] + [DataRow(RDFStoreEnums.RDFFormats.NQuads)] + [DataRow(RDFStoreEnums.RDFFormats.TriX)] + [DataRow(RDFStoreEnums.RDFFormats.TriG)] + public void ShouldImportFromStreamWithEnabledDatatypeDiscovery(RDFStoreEnums.RDFFormats format) + { + MemoryStream stream = new MemoryStream(); + RDFMemoryStore store1 = new RDFMemoryStore(); + RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFPlainLiteral("lit", "en-US")); + RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFResource("http://ex/obj/")); + store1.AddQuadruple(quadruple1) + .AddQuadruple(quadruple2) + .MergeGraph(new RDFGraph() + .AddDatatype(new RDFDatatype(new Uri($"ex:mydtQQ{(int)format}"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ + new RDFPatternFacet("^ex$") ]))); + store1.ToStream(format, stream); + RDFMemoryStore store2 = RDFMemoryStore.FromStream(format, new MemoryStream(stream.ToArray()), true); + + Assert.IsNotNull(store2); + Assert.IsTrue(store2.QuadruplesCount == 9); + Assert.IsTrue(store2.Equals(store1)); + //Test that automatic datatype discovery happened successfully + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtQQ{(int)format}").TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING); + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtQQ{(int)format}").Facets.Single() is RDFPatternFacet fct && fct.Pattern == "^ex$"); + } + [DataTestMethod] [DataRow(RDFStoreEnums.RDFFormats.NQuads)] [DataRow(RDFStoreEnums.RDFFormats.TriX)] @@ -1262,6 +1338,32 @@ public async Task ShouldImportFromStreamAsync(RDFStoreEnums.RDFFormats format) Assert.IsTrue(store2.Equals(store1)); } + [DataTestMethod] + [DataRow(RDFStoreEnums.RDFFormats.NQuads)] + [DataRow(RDFStoreEnums.RDFFormats.TriX)] + [DataRow(RDFStoreEnums.RDFFormats.TriG)] + public async Task ShouldImportFromStreamAsyncWithEnabledDatatypeDiscovery(RDFStoreEnums.RDFFormats format) + { + MemoryStream stream = new MemoryStream(); + RDFMemoryStore store1 = new RDFMemoryStore(); + RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFPlainLiteral("lit", "en-US")); + RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ex/ctx/"), new RDFResource("http://ex/subj/"), new RDFResource("http://ex/pred/"), new RDFResource("http://ex/obj/")); + store1.AddQuadruple(quadruple1) + .AddQuadruple(quadruple2) + .MergeGraph(new RDFGraph() + .AddDatatype(new RDFDatatype(new Uri($"ex:mydtQ{(int)format}"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ + new RDFPatternFacet("^ex$") ]))); + store1.ToStream(format, stream); + RDFMemoryStore store2 = await RDFMemoryStore.FromStreamAsync(format, new MemoryStream(stream.ToArray()), true); + + Assert.IsNotNull(store2); + Assert.IsTrue(store2.QuadruplesCount == 9); + Assert.IsTrue(store2.Equals(store1)); + //Test that automatic datatype discovery happened successfully + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtQ{(int)format}").TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING); + Assert.IsTrue(RDFDatatypeRegister.GetDatatype($"ex:mydtQ{(int)format}").Facets.Single() is RDFPatternFacet fct && fct.Pattern == "^ex$"); + } + [DataTestMethod] [DataRow(RDFStoreEnums.RDFFormats.NQuads)] [DataRow(RDFStoreEnums.RDFFormats.TriX)] @@ -1296,6 +1398,28 @@ public void ShouldImportFromDataTable() Assert.IsTrue(store2.Equals(store1)); } + [TestMethod] + public void ShouldImportFromDataTableWithEnabledDatatypeDiscovery() + { + RDFMemoryStore store1 = new RDFMemoryStore(); + RDFQuadruple quadruple1 = new RDFQuadruple(new RDFContext("http://ctx/"), new RDFResource("http://subj/"), new RDFResource("http://pred/"), new RDFPlainLiteral("lit", "en-US")); + RDFQuadruple quadruple2 = new RDFQuadruple(new RDFContext("http://ctx/"), new RDFResource("http://subj/"), new RDFResource("http://pred/"), new RDFResource("http://obj/")); + store1.AddQuadruple(quadruple1) + .AddQuadruple(quadruple2) + .MergeGraph(new RDFGraph() + .AddDatatype(new RDFDatatype(new Uri("ex:mydtQ"), RDFModelEnums.RDFDatatypes.XSD_STRING, [ + new RDFPatternFacet("^ex$") ]))); + DataTable table = store1.ToDataTable(); + RDFMemoryStore store2 = RDFMemoryStore.FromDataTable(table, true); + + Assert.IsNotNull(store2); + Assert.IsTrue(store2.QuadruplesCount == 9); + Assert.IsTrue(store2.Equals(store1)); + //Test that automatic datatype discovery happened successfully + Assert.IsTrue(RDFDatatypeRegister.GetDatatype("ex:mydtQ").TargetDatatype == RDFModelEnums.RDFDatatypes.XSD_STRING); + Assert.IsTrue(RDFDatatypeRegister.GetDatatype("ex:mydtQ").Facets.Single() is RDFPatternFacet fct && fct.Pattern == "^ex$"); + } + [TestMethod] public void ShouldImportEmptyFromDataTable() { diff --git a/RDFSharp/Model/RDFGraph.cs b/RDFSharp/Model/RDFGraph.cs index 0e5c57d5..35016460 100644 --- a/RDFSharp/Model/RDFGraph.cs +++ b/RDFSharp/Model/RDFGraph.cs @@ -671,7 +671,8 @@ public static RDFGraph FromFile(RDFModelEnums.RDFFormats rdfFormat, string filep /// /// Reads a graph from a stream of the given RDF format. /// - public static RDFGraph FromStream(RDFModelEnums.RDFFormats rdfFormat, Stream inputStream, bool enableDatatypeDiscovery=false) => FromStream(rdfFormat, inputStream, null, enableDatatypeDiscovery); + public static RDFGraph FromStream(RDFModelEnums.RDFFormats rdfFormat, Stream inputStream, bool enableDatatypeDiscovery=false) + => FromStream(rdfFormat, inputStream, null, enableDatatypeDiscovery); internal static RDFGraph FromStream(RDFModelEnums.RDFFormats rdfFormat, Stream inputStream, Uri graphContext, bool enableDatatypeDiscovery=false) { #region Guards diff --git a/RDFSharp/Store/Engines/RDFMemoryStore.cs b/RDFSharp/Store/Engines/RDFMemoryStore.cs index 82721bc2..9183ffa6 100644 --- a/RDFSharp/Store/Engines/RDFMemoryStore.cs +++ b/RDFSharp/Store/Engines/RDFMemoryStore.cs @@ -689,7 +689,7 @@ public RDFMemoryStore DifferenceWith(RDFStore store) /// /// Reads a memory store from a file of the given RDF format. /// - public static RDFMemoryStore FromFile(RDFStoreEnums.RDFFormats rdfFormat, string filepath) + public static RDFMemoryStore FromFile(RDFStoreEnums.RDFFormats rdfFormat, string filepath, bool enableDatatypeDiscovery=false) { #region Guards if (string.IsNullOrWhiteSpace(filepath)) @@ -711,19 +711,29 @@ public static RDFMemoryStore FromFile(RDFStoreEnums.RDFFormats rdfFormat, string memStore = RDFTriG.Deserialize(filepath); break; } + + #region Datatype Discovery + if (enableDatatypeDiscovery) + { + foreach (RDFGraph graph in memStore.ExtractGraphs()) + foreach (RDFDatatype datatypeDefinition in graph.ExtractDatatypeDefinitions()) + RDFDatatypeRegister.AddDatatype(datatypeDefinition); + } + #endregion + return memStore; } /// /// Asynchronously reads a memory store from a file of the given RDF format. /// - public static Task FromFileAsync(RDFStoreEnums.RDFFormats rdfFormat, string filepath) - => Task.Run(() => FromFile(rdfFormat, filepath)); + public static Task FromFileAsync(RDFStoreEnums.RDFFormats rdfFormat, string filepath, bool enableDatatypeDiscovery=false) + => Task.Run(() => FromFile(rdfFormat, filepath, enableDatatypeDiscovery)); /// /// Reads a memory store from a stream of the given RDF format. /// - public static RDFMemoryStore FromStream(RDFStoreEnums.RDFFormats rdfFormat, Stream inputStream) + public static RDFMemoryStore FromStream(RDFStoreEnums.RDFFormats rdfFormat, Stream inputStream, bool enableDatatypeDiscovery=false) { #region Guards if (inputStream == null) @@ -743,19 +753,29 @@ public static RDFMemoryStore FromStream(RDFStoreEnums.RDFFormats rdfFormat, Stre memStore = RDFTriG.Deserialize(inputStream); break; } + + #region Datatype Discovery + if (enableDatatypeDiscovery) + { + foreach (RDFGraph graph in memStore.ExtractGraphs()) + foreach (RDFDatatype datatypeDefinition in graph.ExtractDatatypeDefinitions()) + RDFDatatypeRegister.AddDatatype(datatypeDefinition); + } + #endregion + return memStore; } /// /// Asynchronously reads a memory store from a stream of the given RDF format. /// - public static Task FromStreamAsync(RDFStoreEnums.RDFFormats rdfFormat, Stream inputStream) - => Task.Run(() => FromStream(rdfFormat, inputStream)); + public static Task FromStreamAsync(RDFStoreEnums.RDFFormats rdfFormat, Stream inputStream, bool enableDatatypeDiscovery=false) + => Task.Run(() => FromStream(rdfFormat, inputStream, enableDatatypeDiscovery)); /// /// Reads a memory store from a datatable with "Context-Subject-Predicate-Object" columns. /// - public static RDFMemoryStore FromDataTable(DataTable table) + public static RDFMemoryStore FromDataTable(DataTable table, bool enableDatatypeDiscovery=false) { #region Guards if (table == null) @@ -767,6 +787,8 @@ public static RDFMemoryStore FromDataTable(DataTable table) #endregion RDFMemoryStore memStore = new RDFMemoryStore(); + + #region Parse Table foreach (DataRow tableRow in table.Rows) { #region CONTEXT @@ -811,19 +833,30 @@ public static RDFMemoryStore FromDataTable(DataTable table) memStore.AddQuadruple(new RDFQuadruple(new RDFContext(rowCtx.ToString()), (RDFResource)rowSubj, (RDFResource)rowPred, (RDFLiteral)rowObj)); #endregion } + #endregion + + #region Datatype Discovery + if (enableDatatypeDiscovery) + { + foreach (RDFGraph graph in memStore.ExtractGraphs()) + foreach (RDFDatatype datatypeDefinition in graph.ExtractDatatypeDefinitions()) + RDFDatatypeRegister.AddDatatype(datatypeDefinition); + } + #endregion + return memStore; } /// /// Asynchronously reads a memory store from a datatable with "Context-Subject-Predicate-Object" columns. /// - public static Task FromDataTableAsync(DataTable table) - => Task.Run(() => FromDataTable(table)); + public static Task FromDataTableAsync(DataTable table, bool enableDatatypeDiscovery=false) + => Task.Run(() => FromDataTable(table, enableDatatypeDiscovery)); /// /// Reads a memory store by trying to dereference the given Uri /// - public static RDFMemoryStore FromUri(Uri uri, int timeoutMilliseconds = 20000) + public static RDFMemoryStore FromUri(Uri uri, int timeoutMilliseconds=20000, bool enableDatatypeDiscovery=false) { #region Guards if (uri == null) @@ -880,14 +913,23 @@ public static RDFMemoryStore FromUri(Uri uri, int timeoutMilliseconds = 20000) throw new RDFStoreException("Cannot read RDF memory store from Uri because: " + ex.Message); } + #region Datatype Discovery + if (enableDatatypeDiscovery) + { + foreach (RDFGraph graph in memStore.ExtractGraphs()) + foreach (RDFDatatype datatypeDefinition in graph.ExtractDatatypeDefinitions()) + RDFDatatypeRegister.AddDatatype(datatypeDefinition); + } + #endregion + return memStore; } /// /// Asynchronously reads a memory store by trying to dereference the given Uri /// - public static Task FromUriAsync(Uri uri, int timeoutMilliseconds = 20000) - => Task.Run(() => FromUri(uri, timeoutMilliseconds)); + public static Task FromUriAsync(Uri uri, int timeoutMilliseconds=20000, bool enableDatatypeDiscovery=false) + => Task.Run(() => FromUri(uri, timeoutMilliseconds, enableDatatypeDiscovery)); #endregion #endregion