From cc797abe8d204440c03f84e467376a1093f43f9f Mon Sep 17 00:00:00 2001 From: Oliver Maus Date: Tue, 21 Jan 2025 17:22:45 +0100 Subject: [PATCH 1/4] Add function to check for URIs --- src/ControlledVocabulary/CvTerm.fs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ControlledVocabulary/CvTerm.fs b/src/ControlledVocabulary/CvTerm.fs index a6dbcea..0b00182 100644 --- a/src/ControlledVocabulary/CvTerm.fs +++ b/src/ControlledVocabulary/CvTerm.fs @@ -1,5 +1,9 @@ namespace ControlledVocabulary + +open FSharpAux + + /// Represents a term from a controlled vocabulary (Cv) /// in the form of: id|accession ; name|value ; refUri // ?Maybe [] @@ -9,6 +13,15 @@ type CvTerm = { Name: string RefUri: string } with + + /// + /// Checks if the given accession is an URI. + /// + /// The input accession. + static member checkForUri accession = + let rx = System.Text.RegularExpressions.Regex("^https?:\/\/[a-zA-Z0-9\/]+\/[a-zA-Z]+_[0-9]+\/?$") + rx.Match(accession).Success + static member create( accession: string, name: string, From b288727b5420c90b6cac886157fe1b19a16a541d Mon Sep 17 00:00:00 2001 From: Oliver Maus Date: Tue, 21 Jan 2025 17:35:15 +0100 Subject: [PATCH 2/4] Add function to turn URIs to TANs and use this in `create` function --- src/ControlledVocabulary/CvTerm.fs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ControlledVocabulary/CvTerm.fs b/src/ControlledVocabulary/CvTerm.fs index 0b00182..8e6972c 100644 --- a/src/ControlledVocabulary/CvTerm.fs +++ b/src/ControlledVocabulary/CvTerm.fs @@ -22,13 +22,38 @@ type CvTerm = { let rx = System.Text.RegularExpressions.Regex("^https?:\/\/[a-zA-Z0-9\/]+\/[a-zA-Z]+_[0-9]+\/?$") rx.Match(accession).Success + /// + /// Takes an URI and returns the respective TAN. + /// + /// The input URI. + static member uriToTan (uri : string) : string = + let posLastSlash = String.findIndexBack '/' uri + uri[posLastSlash + 1 ..] + |> String.replace "_" ":" + + /// + /// Creates a CvTerm from a given accession, name and reference. + /// + /// The accession of the term. + /// The name of the term. + /// The term source reference of the term. static member create( accession: string, name: string, ref : string ) = - {Accession = accession; Name = name; RefUri = ref} + let tanAccession = + if CvTerm.checkForUri accession then + CvTerm.uriToTan accession + else accession + + {Accession = tanAccession; Name = name; RefUri = ref} + + /// + /// Creates a CvTerm from a given name. Accession and reference are empty. + /// + /// The name of the term. static member create( name: string ) = From 643b964a1cd3f364bfac4aa8d0b0eafd7764eba6 Mon Sep 17 00:00:00 2001 From: Oliver Maus Date: Tue, 21 Jan 2025 18:41:26 +0100 Subject: [PATCH 3/4] Fix regex --- src/ControlledVocabulary/CvTerm.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ControlledVocabulary/CvTerm.fs b/src/ControlledVocabulary/CvTerm.fs index 8e6972c..ce5dd3a 100644 --- a/src/ControlledVocabulary/CvTerm.fs +++ b/src/ControlledVocabulary/CvTerm.fs @@ -19,7 +19,7 @@ type CvTerm = { /// /// The input accession. static member checkForUri accession = - let rx = System.Text.RegularExpressions.Regex("^https?:\/\/[a-zA-Z0-9\/]+\/[a-zA-Z]+_[0-9]+\/?$") + let rx = System.Text.RegularExpressions.Regex("^https?:\/\/[a-zA-Z0-9\/.]+\/[a-zA-Z]+_[0-9]+\/?$") rx.Match(accession).Success /// From eaa5ddf3a84ed16110fea675d4186f73428cab0d Mon Sep 17 00:00:00 2001 From: Oliver Maus Date: Tue, 21 Jan 2025 18:43:32 +0100 Subject: [PATCH 4/4] Add tests for CvTerm --- .../ControlledVocabulary.Tests.fsproj | 1 + .../ControlledVocabulary.Tests/CvTermTests.fs | 55 +++++++++++++++++++ .../ReferenceObjects.fs | 28 +++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/ControlledVocabulary.Tests/CvTermTests.fs diff --git a/tests/ControlledVocabulary.Tests/ControlledVocabulary.Tests.fsproj b/tests/ControlledVocabulary.Tests/ControlledVocabulary.Tests.fsproj index 3f16e63..340d365 100644 --- a/tests/ControlledVocabulary.Tests/ControlledVocabulary.Tests.fsproj +++ b/tests/ControlledVocabulary.Tests/ControlledVocabulary.Tests.fsproj @@ -8,6 +8,7 @@ + diff --git a/tests/ControlledVocabulary.Tests/CvTermTests.fs b/tests/ControlledVocabulary.Tests/CvTermTests.fs new file mode 100644 index 0000000..ac010b8 --- /dev/null +++ b/tests/ControlledVocabulary.Tests/CvTermTests.fs @@ -0,0 +1,55 @@ +namespace CvTermTests + + +open ControlledVocabulary +open ReferenceObjects + +open Xunit + + +module CheckForUri = + + [] + let ``correct check, actual URL 1`` () = + let check = CvTerm.checkForUri testAccession3 + Assert.True check + + [] + let ``correct check, actual URL 2`` () = + let check = CvTerm.checkForUri "https://purl.org/TO_00000003" + Assert.True check + + [] + let ``correct check, no URL`` () = + let check = CvTerm.checkForUri "purl/123_abc" + Assert.False check + + +module UriToTan = + + [] + let ``correct TAN returned`` () = + let expected = "TO:00000003" + let actual = CvTerm.uriToTan testAccession3 + Assert.Equal(expected, actual) + + +module Create = + + [] + let ``correct CvTerm, primary create function overload`` () = + let expected = testTerm1 + let actual = CvTerm.create(testAccession1, testName1, testRef1) + Assert.Equal(expected, actual) + + [] + let ``correct CvTerm, secondary create function overload (only name given)`` () = + let expected = testTerm4 + let actual = CvTerm.create(testName2) + Assert.Equal(expected, actual) + + [] + let ``correct CvTerm, create function with URL as accession`` () = + let expected = testTerm3 + let actual = CvTerm.create(testAccession3, testName2, testRef2) + Assert.Equal(expected, actual) \ No newline at end of file diff --git a/tests/ControlledVocabulary.Tests/ReferenceObjects.fs b/tests/ControlledVocabulary.Tests/ReferenceObjects.fs index 950cc81..bcb1210 100644 --- a/tests/ControlledVocabulary.Tests/ReferenceObjects.fs +++ b/tests/ControlledVocabulary.Tests/ReferenceObjects.fs @@ -1,18 +1,42 @@ module ReferenceObjects + open ControlledVocabulary + let testAccession1 = "TO:00000001" let testName1 = "Test" let testRef1 = "TO" -let testTerm1 = CvTerm.create(accession = testAccession1, name = testName1, ref = testRef1) +let testTerm1 = { + Accession = testAccession1 + Name = testName1 + RefUri = testRef1 +} let testAccession2 = "TO:00000002" let testName2 = "5" let testRef2 = "TO" -let testTerm2 = CvTerm.create(accession = testAccession2, name = testName2, ref = testRef2) +let testTerm2 = { + Accession = testAccession2 + Name = testName2 + RefUri = testRef2 +} + +let testAccession3 = "http://purl.org/TO_00000003" + +let testTerm3 = { + Accession = "TO:00000003" + Name = testName2 + RefUri = testRef2 +} + +let testTerm4 = { + Accession = "" + Name = testName2 + RefUri = "" +} let ``CvParam with ParamValue.Value`` = CvParam(testTerm1, ParamValue.Value 5) let ``CvParam with ParamValue.CvValue`` = CvParam(testTerm1, ParamValue.CvValue testTerm2)