Skip to content

Commit

Permalink
Rework Validate API
Browse files Browse the repository at this point in the history
  • Loading branch information
kMutagene committed Jan 12, 2024
1 parent 734ec80 commit 0e1e7fb
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 192 deletions.
18 changes: 14 additions & 4 deletions arc-validate.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sln", "sln", "{B3F07465-210
Dockerfile = Dockerfile
ErrorClassOntology.obo = ErrorClassOntology.obo
global.json = global.json
playground.fsx = playground.fsx
README.md = README.md
TestOntology.obo = TestOntology.obo
playgrounds\workingGraph.md = playgrounds\workingGraph.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6275F297-567B-421B-B055-4F88B2785765}"
Expand Down Expand Up @@ -44,6 +44,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".ci", ".ci", "{66A8015E-565
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "playgrounds", "playgrounds", "{7994D526-5B21-4EBD-9CCB-EFA04EE303CF}"
ProjectSection(SolutionItems) = preProject
playgrounds\arc-validation-packages.fsx = playgrounds\arc-validation-packages.fsx
playgrounds\argu.fsx = playgrounds\argu.fsx
playgrounds\codeGeneratorScripting.fsx = playgrounds\codeGeneratorScripting.fsx
playgrounds\errorClassesStatic.fsx = playgrounds\errorClassesStatic.fsx
playgrounds\expectoPlayground.fsx = playgrounds\expectoPlayground.fsx
playgrounds\getAnnotationTableCvPs.fsx = playgrounds\getAnnotationTableCvPs.fsx
playgrounds\github-api.fsx = playgrounds\github-api.fsx
playgrounds\graphModelIOTest.fsx = playgrounds\graphModelIOTest.fsx
playgrounds\graphoscopePlayground.fsx = playgrounds\graphoscopePlayground.fsx
playgrounds\playground.fsx = playgrounds\playground.fsx
EndProjectSection
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCValidationPackages", "src\ARCValidationPackages\ARCValidationPackages.fsproj", "{CF14C74E-20D2-4EC9-B11E-357BFD1244CB}"
EndProject
Expand All @@ -57,16 +69,14 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCExpect.Tests", "tests\AR
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "arcGraph_prototypes", "arcGraph_prototypes", "{02699157-EFC4-4E1A-94CC-B9825E2D1CB8}"
ProjectSection(SolutionItems) = preProject
carepaket.fsx = carepaket.fsx
playgrounds\arcGraph_playgrounds\prototype_v0.1.0.fsx = playgrounds\arcGraph_playgrounds\prototype_v0.1.0.fsx
playgrounds\arcGraph_playgrounds\prototype_v0.1.1.fsx = playgrounds\arcGraph_playgrounds\prototype_v0.1.1.fsx
playgrounds\arcGraph_playgrounds\prototype_v0.2.0.fsx = playgrounds\arcGraph_playgrounds\prototype_v0.2.0.fsx
playgrounds\arcGraph_playgrounds\prototype_v0.2.1.fsx = playgrounds\arcGraph_playgrounds\prototype_v0.2.1.fsx
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demo_notebooks", "demo_notebooks", "{A83F65C9-925E-437C-A457-EF8B9C6B154D}"
ProjectSection(SolutionItems) = preProject
playgrounds\demo_notebooks\demo_ARCGraph.ipynb = playgrounds\demo_notebooks\demo_ARCGraph.ipynb
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "qcPackage_prototypes", "qcPackage_prototypes", "{9B3B6E39-DB2F-4A91-944B-EFAAD961FCE7}"
ProjectSection(SolutionItems) = preProject
Expand Down
13 changes: 8 additions & 5 deletions playgrounds/qcPackage_prototypes/invenio_prototype_v0.2.0.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ let outDir = arcDir

let absoluteDirectoryPaths = FileSystem.parseRelativeDirectoryPaths arcDir
let absoluteFilePaths = FileSystem.parseRelativeFilePaths arcDir

let invFileTokens =
Investigation.parseMetadataSheetsFromTokens() absoluteFilePaths
|> List.concat
Expand All @@ -51,13 +52,15 @@ let invFileTokens =

let cases = [
testList INVMSO.``Investigation Metadata``.INVESTIGATION.key.Name [
ARCExpect.validate (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``.Name) {
ARCExpect.validationCase (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``.Name) {
invFileTokens
|> Validate.ByTerm.contains INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``
|> Validate.ParamCollection.ContainsParamWithTerm
INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``
}
ARCExpect.validate (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``.Name) {
cvParams
|> Validate.ByTerm.contains INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``
ARCExpect.validationCase (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``.Name) {
invFileTokens
|> Validate.ParamCollection.ContainsParamWithTerm
INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``
}
]
]
2 changes: 1 addition & 1 deletion src/ARCExpect/TestGeneration/Critical/ARCFileSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module FileSystem =
testList "FileSystem" [
testList "Investigation" [
validationCase (TestID.Name "Investigation File") {
relativeFilePaths |> Validate.ByValue.containsValue "isa.investigation.xlsx"
relativeFilePaths |> Validate.ParamCollection.ContainsParamWithValue "isa.investigation.xlsx"
}
]
]
4 changes: 2 additions & 2 deletions src/ARCExpect/TestGeneration/Critical/ARCISA.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ module ISA =
testList INVMSO.``Investigation Metadata``.INVESTIGATION.key.Name [
validationCase (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``.Name) {
cvParams
|> Validate.ByTerm.contains INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``
|> Validate.ParamCollection.ContainsParamWithTerm INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Title``
}
validationCase (TestID.Name INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``.Name) {
cvParams
|> Validate.ByTerm.contains INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``
|> Validate.ParamCollection.ContainsParamWithTerm INVMSO.``Investigation Metadata``.INVESTIGATION.``Investigation Description``
}
]
]
242 changes: 120 additions & 122 deletions src/ARCExpect/ValidationFunctions.fs
Original file line number Diff line number Diff line change
@@ -1,165 +1,163 @@
namespace ARCExpect.Validate
namespace ARCExpect

open ControlledVocabulary
open ARCExpect
open ARCTokenization.StructuralOntology


/// <summary>
/// Validation functions to perform value-based validation on IParams
/// Top level API for performing validation.
/// </summary>
type ByValue =
static member notEmpty (cvp:CvParam) =
match CvParam.isEmpty cvp with
| false -> ()
| true ->
cvp
|> ErrorMessage.ofCvParam "is empty."
|> Expecto.Tests.failtestNoStackf "%s"

static member notEmpty (ip : #IParam) =
match Param.isEmpty ip with
| false -> ()
| true ->
ip
|> ErrorMessage.ofIParam "is empty."
|> Expecto.Tests.failtestNoStackf "%s"

static member equals (targetValue : System.IConvertible) (ip : #IParam) =
let act = Param.getValue ip
match targetValue = act with
| true -> ()
| false ->
ip
|> ErrorMessage.ofIParam $"should equal {targetValue}."
|> Expecto.Tests.failtestNoStackf "%s"

module Validate =

/// <summary>
/// tests wether any of the CvParams in the given collection has the expectedValue
/// Validation functions to perform on any type implementing the `IParam` interface.
/// </summary>
/// <param name="expectedValue">the value expected to occur in at least 1 CvParam in the given collection</param>
static member containsValue (expectedValue : #System.IConvertible) (set : #seq<#IParam>) =
match Seq.exists (fun (ip : #IParam)-> (ip.Value |> ParamValue.getValue) = (expectedValue :> System.IConvertible)) set with
| true -> ()
| false ->
expectedValue
|> ErrorMessage.ofValue $"does not exist"
|> Expecto.Tests.failtestNoStackf "%s"
type Param =

/// <summary>
/// Validates that the value of the given Param is not empty (meaning it is not an empty string: "").
/// </summary>
/// <param name="param">The param to validate</param>
static member ValueIsNotEmpty (param : #IParam) =
match Param.isEmpty param with
| false -> ()
| true ->
param
|> ErrorMessage.ofIParam "is empty."
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// tests wether any of the CvParams equal the expectedParam by value
/// </summary>
/// <param name="expectedParam">the Cvparam for which it is expected to share it's value with at least one Cvparam in the collection</param>
static member containsParam (expectedParam : #IParam) (set : #seq<#IParam>) =
let tmp =
Param.getParamValue expectedParam
|> ParamValue.getValue
match Seq.exists (fun (ip : #IParam)-> (ip.Value |> ParamValue.getValue) = tmp) set with
| true -> ()
| false ->
expectedParam
|> ErrorMessage.ofIParam $"does not exist"
|> Expecto.Tests.failtestNoStackf "%s"


static member isMatch (pattern:string) =
fun (ip : #IParam) ->
/// <summary>

Check warning on line 29 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is invalid: unknown parameter 'expectedValue'

Check warning on line 29 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is incomplete: no documentation for parameter 'targetValue'

Check warning on line 29 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is invalid: unknown parameter 'expectedValue'

Check warning on line 29 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is incomplete: no documentation for parameter 'targetValue'
/// Validates if the value of the given Param is equal to the expected value.
/// </summary>
/// <param name="expectedValue">The expected value to validate against</param>
/// <param name="param">The param to validate</param>
static member ValueIsEqualTo (targetValue : System.IConvertible) (param : #IParam) =
let act = Param.getValue param
match targetValue = act with
| true -> ()
| false ->
param
|> ErrorMessage.ofIParam $"should equal {targetValue}."
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// Validates if the term of the given Param is equal to the expected term.
/// </summary>
/// <param name="expectedTerm">The expected term to validate against</param>
/// <param name="param">The param to validate</param>
static member TermIsEqualTo (expectedTerm:CvTerm) (param : #IParam) =
match (Param.getTerm param) = expectedTerm with
| true -> ()
| false ->
param
|> ErrorMessage.ofIParam $"should equal {expectedTerm}."
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// Validates if the value of the given Param matches a regex pattern.
/// </summary>
/// <param name="pattern">The regex pattern that the value should match</param>
/// <param name="param">The param to validate</param>
static member ValueMatchesPattern (pattern:string) (param : #IParam) =
let tmp =
Param.getParamValue ip
Param.getParamValue param
|> ParamValue.getValue
|> string
match System.Text.RegularExpressions.Regex.IsMatch(tmp,pattern) with
| true -> ()
| false ->
ip
param
|> ErrorMessage.ofIParam "is invalid."
|> Expecto.Tests.failtestNoStackf "%s"


static member isMatch (regex:System.Text.RegularExpressions.Regex) =
fun (ip : #IParam) ->
/// <summary>

Check warning on line 73 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is invalid: unknown parameter 'pattern'

Check warning on line 73 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is incomplete: no documentation for parameter 'regex'

Check warning on line 73 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is invalid: unknown parameter 'pattern'

Check warning on line 73 in src/ARCExpect/ValidationFunctions.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is incomplete: no documentation for parameter 'regex'
/// Validates if the value of the given Param matches a regex.
/// </summary>
/// <param name="pattern">The regex that the value should match</param>
/// <param name="param">The param to validate</param>
static member ValueMatchesRegex (regex:System.Text.RegularExpressions.Regex) (param : #IParam) =
let tmp =
Param.getParamValue ip
Param.getParamValue param
|> ParamValue.getValue
|> string
match regex.IsMatch(tmp) with
| true -> ()
| false ->
ip
param
|> ErrorMessage.ofIParam "is invalid."
|> Expecto.Tests.failtestNoStackf "%s"


static member isMatchBy (validator:string -> bool) =
fun (ip : #IParam) ->

/// <summary>
/// Validates if the value of the given Param satisfies a predicate (meaning a function that for a given Param returns either true or false)
/// </summary>
/// <param name="predicate">The predicate that the Param should satisfy</param>
/// <param name="param">The param to validate</param>
static member ValueSatisfiesPredicate (predicate: System.IConvertible -> bool) (param : #IParam) =
let tmp =
Param.getParamValue ip
Param.getParamValue param
|> ParamValue.getValue
|> string
match validator tmp with
| true -> ()
| false ->
ip
|> ErrorMessage.ofIParam "is invalid."
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// Validation functions to perform term-based validation on IParams
/// </summary>
type ByTerm =

/// Compares by Term
static member equals (target:CvTerm) =
fun (ip : #IParam) ->
match (Param.getTerm ip) = target with
| true -> ()
| false ->
ip
|> ErrorMessage.ofIParam $"should equal {target}."
|> Expecto.Tests.failtestNoStackf "%s"
if not (predicate tmp) then
param
|> ErrorMessage.ofIParam "is invalid."
|> Expecto.Tests.failtestNoStackf "%s"

/// Compares by Term
static member equals (target:CvParam) =
fun (ip : #IParam) ->
match (Param.getTerm ip) = (CvParam.getTerm target) with
| true -> ()
| false ->
ip
|> ErrorMessage.ofIParam $"should equal {target}."
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// tests wether any of the CvParams in the given collection is annotated with the expectedTerm
/// Validation functions to perform on a collection containing any type implementing the `IParam` interface.
/// </summary>
/// <param name="expectedTerm">the term expected to occur in at least 1 CvParam in the given collection</param>
static member contains (expectedTerm:CvTerm) =
fun (set : #seq<#IParam>) ->
match Seq.exists (fun e -> Param.getTerm e = expectedTerm) set with
type ParamCollection =

/// <summary>
/// Validates if at least one Param with the expected value in the given collection exists.
/// </summary>
/// <param name="expectedValue">the value expected to occur in at least 1 Param in the given collection</param>
/// <param name="paramCollection">The param collection to validate</param>
static member ContainsParamWithValue (expectedValue : #System.IConvertible) (paramCollection : #seq<#IParam>) =
match Seq.exists (fun (param : #IParam)-> (param.Value |> ParamValue.getValue) = (expectedValue :> System.IConvertible)) paramCollection with
| true -> ()
| false ->
expectedTerm
|> ErrorMessage.ofCvTerm "is missing."
expectedValue
|> ErrorMessage.ofValue $"does not exist"
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// tests wether any of the CvParams equal the expectedParam by term
/// </summary>
/// <param name="expectedParam">the Cvparam for which it is expected to share it's term with at least one Cvparam in the collection</param>
static member contains (expectedParam : IParam) =
fun (set: #seq<#IParam>) ->
match Seq.exists (fun e -> Param.getTerm e = Param.getTerm expectedParam) set with
/// <summary>
/// Validates if at least one Param with the expected term in the given collection exists.
/// </summary>
/// <param name="expectedTerm">the term expected to occur in at least 1 Param in the given collection</param>
/// <param name="paramCollection">The param collection to validate</param>
static member ContainsParamWithTerm (expectedTerm : CvTerm) (paramCollection: #seq<#IParam>) =
match Seq.exists (fun e -> Param.getTerm e = expectedTerm) paramCollection with
| true -> ()
| false ->
expectedParam
|> ErrorMessage.ofIParam "is missing."
expectedTerm
|> ErrorMessage.ofCvTerm $"does not exist"
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// Validates if the given Param is contained in the given collection át least once.
/// </summary>
/// <param name="expectedParam">the param expected to occur at least once in the given collection</param>
/// <param name="paramCollection">The param collection to validate</param>
static member ContainsParam (expectedParam : #IParam) (paramCollection : #seq<#IParam>) =

let tmp =
Param.getParamValue expectedParam
|> ParamValue.getValue
// this is incomplete and does not exactly perform what the name advertises
// (e.g., it only checks value but not term, or even if the Params are Cv or User)
match Seq.exists (fun (param : #IParam)-> (param.Value |> ParamValue.getValue) = tmp) paramCollection with
| true -> ()
| false ->
expectedParam
|> ErrorMessage.ofIParam $"does not exist"
|> Expecto.Tests.failtestNoStackf "%s"

/// <summary>
/// Validation functions to perform context-dependent tests on CvParams representing a special kind of object (e.g. multiple properties of a Person, an Email, etc.)
/// </summary>
type ByObject =

static member email (ip : #IParam) =
ip |> ByValue.isMatch StringValidationPattern.email
ip |> ByTerm.equals INVMSO.``Investigation Metadata``.``INVESTIGATION CONTACTS``.``Investigation Person Email``
/// <summary>
/// Validates wether the given Param's value is an email that matches a pre-defined regex pattern ("^[^@\s]+@[^@\s]+\.[^@\s]+$")
/// and wether the param is annotated with the term `Investigation Person Email`
/// </summary>
/// <param name="param"></param>
let email (param : #IParam) =
param |> Param.ValueMatchesRegex StringValidationPattern.email
param |> Param.TermIsEqualTo INVMSO.``Investigation Metadata``.``INVESTIGATION CONTACTS``.``Investigation Person Email``
Loading

0 comments on commit 0e1e7fb

Please sign in to comment.