diff --git a/arc-validate.sln b/arc-validate.sln index c7e06f6..578d24f 100644 --- a/arc-validate.sln +++ b/arc-validate.sln @@ -61,6 +61,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demo_notebooks", "demo_notebooks", "{A83F65C9-925E-437C-A457-EF8B9C6B154D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "qcPackage_prototypes", "qcPackage_prototypes", "{9B3B6E39-DB2F-4A91-944B-EFAAD961FCE7}" + ProjectSection(SolutionItems) = preProject + playgrounds\qcPackage_prototypes\pride_prototype_v0.1.0.fsx = playgrounds\qcPackage_prototypes\pride_prototype_v0.1.0.fsx + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{DB01DF70-3713-4445-AC79-A09ECE093294}" EndProject @@ -68,7 +71,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{588E EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharpConsole", "tests\FSharpConsole\FSharpConsole.fsproj", "{DE9F79F6-ABA2-4940-AEB6-D969AE752E6F}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Common", "tests\Common\Common.fsproj", "{C41FAD1A-6E44-4C11-B915-CD928E0ED72B}" +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Common", "tests\Common\Common.fsproj", "{C41FAD1A-6E44-4C11-B915-CD928E0ED72B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "arc-validate", "arc-validate", "{E6A037FA-C367-4C2A-9B87-2A04CA25D3C9}" EndProject diff --git a/playgrounds/qcPackage_prototypes/pride_prototype_v0.1.0.fsx b/playgrounds/qcPackage_prototypes/pride_prototype_v0.1.0.fsx index c5b1475..d111b87 100644 --- a/playgrounds/qcPackage_prototypes/pride_prototype_v0.1.0.fsx +++ b/playgrounds/qcPackage_prototypes/pride_prototype_v0.1.0.fsx @@ -50,9 +50,6 @@ let invFileTokens = |> Seq.concat |> Seq.map snd -Investigation.parseMetadataSheetsFromTokens() absoluteFilePaths |> List.concat |> Seq.iter (Param.getCvName >> printfn "%s") -Investigation.parseMetadataSheetsFromTokens() absoluteFilePaths |> List.concat |> Seq.iter (Param.getTerm >> printfn "%A") - let invFileTokensNoMdSecKeys = invFileTokens |> Seq.filter (Param.getValue >> (<>) Terms.StructuralTerms.metadataSectionKey.Name) @@ -78,6 +75,32 @@ let commis = |> Seq.filter (Param.getTerm >> (=) Terms.StructuralTerms.userComment) + +// Helper functions: + +type ParamCollection = + + static member AllItemsSatisfyPredicate (predicate : #IParam -> bool) (paramCollection : #seq<#IParam>) = + use en = paramCollection.GetEnumerator() + let rec loop failString = + match en.MoveNext() with + | true -> + if predicate en.Current |> not then + let em = ErrorMessage.ofIParam $"does not satisfy predicate" en.Current + loop $"{failString}\n{em}" + else loop failString + | false -> failString + let failString = loop "" + if String.isNullOrEmpty failString |> not then + Expecto.Tests.failtestNoStackf "%s" failString + + +let testl = Seq.take 5 invFileTokens |> List.ofSeq + +ParamCollection.AllItemsSatisfyPredicate (fun p -> p.Name = "Term Source Name") testl + + + // Validation Cases: let cases = diff --git a/src/ARCExpect/ErrorMessage.fs b/src/ARCExpect/ErrorMessage.fs index 504200c..35f693b 100644 --- a/src/ARCExpect/ErrorMessage.fs +++ b/src/ARCExpect/ErrorMessage.fs @@ -85,6 +85,45 @@ type ErrorMessage = str.AppendFormat(" > line '{0}'", line) |> ignore | None -> () + match Param.tryGetValueOfCvParamAttr "Position" iParam with + | Some position -> + str.AppendFormat(" > position '{0}'", position) |> ignore + | None -> () + str.ToString() + + + static member ofIParamCollection error iParamCollection = + + let iParam = Seq.head iParamCollection + + let str = new StringBuilder() + str.AppendFormat("['{0}', ..] {1}\n", Param.getCvName iParam, error) |> ignore + + match Param.tryGetValueOfCvParamAttr "FilePath" iParam with + | Some path -> + str.AppendFormat(" > filePath '{0}'\n", path) |> ignore + | None -> () + + match Param.tryGetValueOfCvParamAttr "Worksheet" iParam with + | Some sheet -> + str.AppendFormat(" > sheet '{0}'", sheet) |> ignore + | None -> () + + match Param.tryGetValueOfCvParamAttr "Row" iParam with + | Some row -> + str.AppendFormat(" > row '{0}'", row) |> ignore + | None -> () + + match Param.tryGetValueOfCvParamAttr "Column" iParam with + | Some column -> + str.AppendFormat(" > column '{0}'", column) |> ignore + | None -> () + + match Param.tryGetValueOfCvParamAttr "Line" iParam with + | Some line -> + str.AppendFormat(" > line '{0}'", line) |> ignore + | None -> () + match Param.tryGetValueOfCvParamAttr "Position" iParam with | Some position -> str.AppendFormat(" > position '{0}'", position) |> ignore diff --git a/src/ARCExpect/ValidationFunctions.fs b/src/ARCExpect/ValidationFunctions.fs index 641702e..bd6efe9 100644 --- a/src/ARCExpect/ValidationFunctions.fs +++ b/src/ARCExpect/ValidationFunctions.fs @@ -3,6 +3,8 @@ open ControlledVocabulary open ARCExpect open ARCTokenization.StructuralOntology +open FSharpAux + /// /// Top level API for performing validation. @@ -134,7 +136,7 @@ module Validate = |> Expecto.Tests.failtestNoStackf "%s" /// - /// Validates if the given Param is contained in the given collection át least once. + /// Validates if the given Param is contained in the given collection at least once. /// /// the param expected to occur at least once in the given collection /// The param collection to validate @@ -152,6 +154,25 @@ module Validate = |> ErrorMessage.ofIParam $"does not exist" |> Expecto.Tests.failtestNoStackf "%s" + /// + /// Validates if all elements in the given IParam collection satisfy the predicate function. + /// + /// A function that evaluates to true if the element satisfies the requirements. + /// The IParam collection to validate. + static member AllItemsSatisfyPredicate (predicate : #IParam -> bool) (paramCollection : #seq<#IParam>) = + use en = paramCollection.GetEnumerator() + let rec loop failString = + match en.MoveNext() with + | true -> + if predicate en.Current |> not then + let em = ErrorMessage.ofIParam $"does not satisfy predicate" en.Current + loop $"{failString}\n{em}" + else loop failString + | false -> failString + let failString = loop "" + if String.isNullOrEmpty failString |> not then + Expecto.Tests.failtestNoStackf "%s" failString + /// /// Validates wether the given Param's value is an email that matches a pre-defined regex pattern ("^[^@\s]+@[^@\s]+\.[^@\s]+$") diff --git a/tests/ARCExpect.Tests/ARCExpect.Tests.fsproj b/tests/ARCExpect.Tests/ARCExpect.Tests.fsproj index 61d6203..f5fefe8 100644 --- a/tests/ARCExpect.Tests/ARCExpect.Tests.fsproj +++ b/tests/ARCExpect.Tests/ARCExpect.Tests.fsproj @@ -11,6 +11,7 @@ + diff --git a/tests/ARCExpect.Tests/ErrorMessageTests.fs b/tests/ARCExpect.Tests/ErrorMessageTests.fs new file mode 100644 index 0000000..0b61553 --- /dev/null +++ b/tests/ARCExpect.Tests/ErrorMessageTests.fs @@ -0,0 +1,21 @@ +module ErrorMessageTests + + +open Expecto +open ARCExpect +open ControlledVocabulary + + +let dummyIParam = CvParam("test:0", "testTerm", "test", ParamValue.Value "no val") +let dummyIParamColl = List.init 3 (fun _ -> dummyIParam) + + +[] +let ``ErrorMessage tests`` = + testList "ErrorMessage" [ + testList "ofIParamCollection" [ + testCase "resolves correctly" <| fun _ -> + let eMsg = ErrorMessage.ofIParamCollection "does not satisfy" dummyIParamColl + Expect.equal eMsg "['testTerm', ..] does not satisfy\n" "resolved incorrectly" + ] + ] \ No newline at end of file