diff --git a/Directory.Packages.props b/Directory.Packages.props index 77d02835..dcb4614f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -15,7 +15,7 @@ - + diff --git a/build/ProjectInfo.fs b/build/ProjectInfo.fs index cf0aa003..976bc619 100644 --- a/build/ProjectInfo.fs +++ b/build/ProjectInfo.fs @@ -5,19 +5,22 @@ open Helpers let project = "ARCtrl" +let allTestsProject = "tests/All" + /// Dotnet and JS test paths let testProjects = [ "tests/All" - //"tests/Core" - //"tests/Json" - //"tests/Spreadsheet" - //"tests/FileSystem" - //"tests/ARCtrl" - //"tests/Yaml" - //"tests/ValidationPackages" - //"tests/Contract" - //"tests/ROCrate" + "tests/ARCtrl" + "tests/Contract" + "tests/Core" + "tests/CWL" + "tests/FileSystem" + "tests/Json" + "tests/ROCrate" + "tests/Spreadsheet" + "tests/ValidationPackages" + "tests/Yaml" ] /// Native JS test paths diff --git a/build/TestTasks.fs b/build/TestTasks.fs index 6f4eb765..e6654997 100644 --- a/build/TestTasks.fs +++ b/build/TestTasks.fs @@ -36,16 +36,14 @@ module RunTests = let runTestsJs = BuildTask.createFn "runTestsJS" [clean] (fun tp -> if tp.Context.Arguments |> List.exists (fun a -> a.ToLower() = skipTestsFlag.ToLower()) |> not then Trace.traceImportant "Start Js tests" - for path in ProjectInfo.testProjects do - // Setup test results directory after clean - System.IO.Directory.CreateDirectory("./tests/TestingUtils/TestResults/js") |> ignore - // transpile js files from fsharp code - run dotnet $"fable {path} -o {path}/js --nocache" "" - - System.IO.File.Copy(jsHelperFilePath, $"{path}/js/{jsHelperFileName}") |> ignore - // run mocha in target path to execute tests - // "--timeout 20000" is used, because json schema validation takes a bit of time. - run node $"{path}/js/Main.js" "" + // Setup test results directory after clean + System.IO.Directory.CreateDirectory("./tests/TestingUtils/TestResults/js") |> ignore + // transpile js files from fsharp code + run dotnet $"fable {allTestsProject} -o {allTestsProject}/js --nocache" "" + System.IO.File.Copy(jsHelperFilePath, $"{allTestsProject}/js/{jsHelperFileName}") |> ignore + // run mocha in target path to execute tests + // "--timeout 20000" is used, because json schema validation takes a bit of time. + run node $"{allTestsProject}/js/Main.js" "" else Trace.traceImportant "Skipping Js tests" ) @@ -65,13 +63,12 @@ module RunTests = let runTestsPy = BuildTask.createFn "runTestsPy" [clean] (fun tp -> if tp.Context.Arguments |> List.exists (fun a -> a.ToLower() = skipTestsFlag.ToLower()) |> not then Trace.traceImportant "Start Python tests" - for path in ProjectInfo.testProjects do - // Setup test results directory after clean - System.IO.Directory.CreateDirectory("./tests/TestingUtils/TestResults/py") |> ignore - //transpile py files from fsharp code - run dotnet $"fable {path} -o {path}/py --lang python --nocache" "" - // run pyxpecto in target path to execute tests in python - run python $"{path}/py/main.py" "" + // Setup test results directory after clean + System.IO.Directory.CreateDirectory("./tests/TestingUtils/TestResults/py") |> ignore + //transpile py files from fsharp code + run dotnet $"fable {allTestsProject} -o {allTestsProject}/py --lang python --nocache" "" + // run pyxpecto in target path to execute tests in python + run python $"{allTestsProject}/py/main.py" "" else Trace.traceImportant "Skipping Python tests" @@ -81,8 +78,7 @@ module RunTests = if tp.Context.Arguments |> List.exists (fun a -> a.ToLower() = skipTestsFlag.ToLower()) |> not then Trace.traceImportant "Start .NET tests" let dotnetRun = run dotnet "run" - testProjects - |> Seq.iter dotnetRun + dotnetRun allTestsProject else Trace.traceImportant "Skipping .NET tests" ) @@ -105,6 +101,7 @@ module RunTests = run python $"{p}/py/main.py" "" // transpile js files from fsharp code run dotnet $"fable {p} -o {p}/js" "" + System.IO.Directory.CreateDirectory("./tests/TestingUtils/TestResults/js") |> ignore System.IO.File.Copy(jsHelperFilePath, $"{p}/js/{jsHelperFileName}") |> ignore // run mocha in target path to execute tests // "--timeout 20000" is used, because json schema validation takes a bit of time. diff --git a/src/Json/Decode.fs b/src/Json/Decode.fs index a52231f0..720991d0 100644 --- a/src/Json/Decode.fs +++ b/src/Json/Decode.fs @@ -93,9 +93,7 @@ module Decode = decoder.Decode(helpers,value) } - - - let resizeArray (decoder: Decoder<'value>) : Decoder> = + let resizeArrayOrSingleton (decoder: Decoder<'value>) : Decoder> = { new Decoder> with member _.Decode(helpers, value) = if helpers.isArray value then @@ -123,7 +121,7 @@ module Decode = Ok acc ) else - ("", BadPrimitive("an array", value)) |> Error + decoder.Decode(helpers, value) |> Result.map (fun x -> ResizeArray[x]) } let datetime: Decoder = diff --git a/src/Json/Encode.fs b/src/Json/Encode.fs index fabebd65..58c9932c 100644 --- a/src/Json/Encode.fs +++ b/src/Json/Encode.fs @@ -63,4 +63,12 @@ module Encode = let addPropertyToObject (name : string) (value : Json) (obj : Json) = match obj with | Json.Object kvs -> Json.Object (Seq.append kvs [name, value] ) - | _ -> failwith "Expected object" \ No newline at end of file + | _ -> failwith "Expected object" + + let resizeArrayOrSingleton (encoder : 'T -> IEncodable) (values: ResizeArray<'T>) = + if values.Count = 1 then + values.[0] |> encoder + else + values + |> Seq.map encoder + |> Encode.seq \ No newline at end of file diff --git a/src/Json/LDObject.fs b/src/Json/LDObject.fs index a9aae98c..796275a4 100644 --- a/src/Json/LDObject.fs +++ b/src/Json/LDObject.fs @@ -6,8 +6,39 @@ open ARCtrl.ROCrate open Thoth.Json.Core open DynamicObj -module rec LDObject = +module LDContext = + + let decoder : Decoder = + { new Decoder with + member _.Decode(helpers, value) = + if helpers.isObject value then + let getters = Decode.Getters(helpers, value) + let properties = helpers.getProperties value + let builder = + fun (get : Decode.IGetters) -> + let o = LDContext() + for property in properties do + if property <> "@id" && property <> "@type" then + o.SetProperty(property,get.Required.Field property Decode.string) + o + let result = builder getters + match getters.Errors with + | [] -> Ok result + | fst :: _ as errors -> + if errors.Length > 1 then + ("", BadOneOf errors) |> Error + else + Error fst + else + ("", BadPrimitive("an object", value)) |> Error + } + let encoder (ctx: LDContext) = + ctx.GetProperties true + |> Seq.map (fun kv -> kv.Key, kv.Value |> string |> Encode.string ) + |> Encode.object + +module rec LDObject = #if !FABLE_COMPILER let (|SomeObj|_|) = // create generalized option type @@ -45,20 +76,36 @@ module rec LDObject = | _ -> failwith "Unknown type" let rec encoder(obj: LDObject) = - obj.GetProperties true - |> Seq.choose (fun kv -> - let l = kv.Key.ToLower() - if l <> "id" && l <> "schematype" && l <> "additionaltype" then - Some(kv.Key, genericEncoder kv.Value) - else - None + //obj.GetProperties true + //|> Seq.choose (fun kv -> + // let l = kv.Key.ToLower() + // if l <> "id" && l <> "schematype" && l <> "additionaltype" && l <> "@context" then + // Some(kv.Key, genericEncoder kv.Value) + // else + // None - ) - |> Seq.append [ - "@id", Encode.string obj.Id - "@type", Encode.string obj.SchemaType - if obj.AdditionalType.IsSome then - "additionalType", Encode.string obj.AdditionalType.Value + //) + //|> Seq.append [ + // "@id", Encode.string obj.Id + // "@type", LDType.encoder obj.SchemaType + // if obj.AdditionalType.IsSome then + // "additionalType", Encode.string obj.AdditionalType.Value + // match obj.TryGetContext() with + // | Some ctx -> "@context", LDContext.encoder ctx + // | _ -> () + //] + [ + yield "@id", Encode.string obj.Id + yield "@type", Encode.resizeArrayOrSingleton Encode.string obj.SchemaType + if obj.AdditionalType.Count <> 0 then + yield "additionalType", Encode.resizeArrayOrSingleton Encode.string obj.AdditionalType + match obj.TryGetContext() with + | Some ctx -> yield "@context", LDContext.encoder ctx + | _ -> () + for kv in (obj.GetProperties true) do + let l = kv.Key.ToLower() + if l <> "id" && l <> "schematype" && l <> "additionaltype" && l <> "@context" then + yield kv.Key, genericEncoder kv.Value ] |> Encode.object @@ -75,12 +122,15 @@ module rec LDObject = let properties = helpers.getProperties value let builder = fun (get : Decode.IGetters) -> - let t = get.Required.Field "@type" Decode.string + let t = get.Required.Field "@type" (Decode.resizeArrayOrSingleton Decode.string) let id = get.Required.Field "@id" Decode.string - let o = LDObject(id,t) + let context = get.Optional.Field "@context" LDContext.decoder + let at = get.Optional.Field "additionalType" (Decode.resizeArrayOrSingleton Decode.string) + let o = LDObject(id, t, ?additionalType = at) for property in properties do - if property <> "@id" && property <> "@type" then + if property <> "@id" && property <> "@type" && property <> "@context" then o.SetProperty(property,get.Required.Field property (decode(false))) + if context.IsSome then o.SetContext context.Value o let result = builder getters match getters.Errors with diff --git a/src/ROCrate/ArcROCrateMetadata.fs b/src/ROCrate/ArcROCrateMetadata.fs index 2fd930b1..3e976b7e 100644 --- a/src/ROCrate/ArcROCrateMetadata.fs +++ b/src/ROCrate/ArcROCrateMetadata.fs @@ -4,7 +4,7 @@ open DynamicObj type ArcROCrateMetadata(?about : LDObject) as this = - inherit LDObject(id = "ro-crate-metadata",schemaType = "CreativeWork") + inherit LDObject(id = "ro-crate-metadata",schemaType = ResizeArray([|"CreativeWork"|])) do DynObj.setOptionalProperty (nameof about) about this diff --git a/src/ROCrate/DynObjExtensions.fs b/src/ROCrate/DynObjExtensions.fs index 1cb8fe70..a84d676f 100644 --- a/src/ROCrate/DynObjExtensions.fs +++ b/src/ROCrate/DynObjExtensions.fs @@ -12,4 +12,10 @@ module DynObj = | Some value -> value | None -> raise (System.InvalidCastException($"Property '{propertyName}' is set on this '{className}' object but cannot be cast to '{(typeof<'TPropertyValue>).Name}'")) else - raise (System.MissingMemberException($"No property '{propertyName}' set on this '{className}' object although it is mandatory. Was it created correctly?")) \ No newline at end of file + raise (System.MissingMemberException($"No property '{propertyName}' set on this '{className}' object although it is mandatory. Was it created correctly?")) + + let inline tryGetTypedPropertyValueAsResizeArray<'T> (name : string) (obj : DynamicObj) = + match obj.TryGetPropertyValue(name) with + | Some (:? ResizeArray<'T> as ra) -> Some ra + | Some (:? 'T as singleton) -> Some (ResizeArray [singleton]) + | _ -> None \ No newline at end of file diff --git a/src/ROCrate/ISAProfile/Assay.fs b/src/ROCrate/ISAProfile/Assay.fs index 5532ada4..1549799e 100644 --- a/src/ROCrate/ISAProfile/Assay.fs +++ b/src/ROCrate/ISAProfile/Assay.fs @@ -17,7 +17,7 @@ type Assay( ?url, ?variableMeasured ) as this = - inherit Dataset(id, "Assay") + inherit Dataset(id = id, additionalType = ResizeArray[|"Assay"|]) do DynObj.setProperty (nameof identifier) identifier this diff --git a/src/ROCrate/ISAProfile/Data.fs b/src/ROCrate/ISAProfile/Data.fs index 1f4e30ec..81797118 100644 --- a/src/ROCrate/ISAProfile/Data.fs +++ b/src/ROCrate/ISAProfile/Data.fs @@ -13,7 +13,11 @@ type Data( ?encodingFormat, ?disambiguatingDescription ) as this = - inherit LDObject(id = id, schemaType = "schema.org/MediaObject", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"schema.org/MediaObject"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof name) name this diff --git a/src/ROCrate/ISAProfile/Dataset.fs b/src/ROCrate/ISAProfile/Dataset.fs index 52ce4779..c610b138 100644 --- a/src/ROCrate/ISAProfile/Dataset.fs +++ b/src/ROCrate/ISAProfile/Dataset.fs @@ -2,8 +2,12 @@ namespace ARCtrl.ROCrate open DynamicObj open Fable.Core - + /// [] -type Dataset (id: string, ?additionalType: string) = - inherit LDObject(id = id, schemaType = "schema.org/Dataset", ?additionalType = additionalType) +type Dataset (id: string, ?additionalType: ResizeArray) = + inherit LDObject( + id = id, + schemaType = ResizeArray[|"schema.org/Dataset"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) diff --git a/src/ROCrate/ISAProfile/Investigation.fs b/src/ROCrate/ISAProfile/Investigation.fs index 8e08aff7..0588caed 100644 --- a/src/ROCrate/ISAProfile/Investigation.fs +++ b/src/ROCrate/ISAProfile/Investigation.fs @@ -20,7 +20,7 @@ type Investigation( ?url, ?description ) as this = - inherit Dataset(id, "Investigation") + inherit Dataset(id = id, additionalType = ResizeArray[|"Investigation"|]) do DynObj.setProperty (nameof identifier) identifier this diff --git a/src/ROCrate/ISAProfile/LabProcess.fs b/src/ROCrate/ISAProfile/LabProcess.fs index 9abb4fdc..81a8648e 100644 --- a/src/ROCrate/ISAProfile/LabProcess.fs +++ b/src/ROCrate/ISAProfile/LabProcess.fs @@ -17,7 +17,11 @@ type LabProcess( ?endTime, ?disambiguatingDescription ) as this = - inherit LDObject(id = id, schemaType = "bioschemas.org/LabProcess", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"bioschemas.org/LabProcess"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof name) name this DynObj.setProperty (nameof agent) agent this diff --git a/src/ROCrate/ISAProfile/LabProtocol.fs b/src/ROCrate/ISAProfile/LabProtocol.fs index db6a66d4..af8c2d9a 100644 --- a/src/ROCrate/ISAProfile/LabProtocol.fs +++ b/src/ROCrate/ISAProfile/LabProtocol.fs @@ -18,7 +18,11 @@ type LabProtocol( ?reagent, ?computationalTool ) as this = - inherit LDObject(id = id, schemaType = "bioschemas.org/LabProtocol", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"bioschemas.org/LabProtocol"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setOptionalProperty (nameof name) name this DynObj.setOptionalProperty (nameof intendedUse) intendedUse this diff --git a/src/ROCrate/ISAProfile/Person.fs b/src/ROCrate/ISAProfile/Person.fs index b3076813..01e8ea32 100644 --- a/src/ROCrate/ISAProfile/Person.fs +++ b/src/ROCrate/ISAProfile/Person.fs @@ -20,7 +20,11 @@ type Person( ?faxNumber, ?disambiguatingDescription ) as this= - inherit LDObject(id = id, schemaType = "schema.org/Person", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"schema.org/Person"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof givenName) givenName this diff --git a/src/ROCrate/ISAProfile/PropertyValue.fs b/src/ROCrate/ISAProfile/PropertyValue.fs index 730ad7a7..b42f9ff7 100644 --- a/src/ROCrate/ISAProfile/PropertyValue.fs +++ b/src/ROCrate/ISAProfile/PropertyValue.fs @@ -15,7 +15,11 @@ type PropertyValue( ?valueReference, ?additionalType ) as this = - inherit LDObject(id = id, schemaType = "schema.org/PropertyValue", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"schema.org/PropertyValue"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof name) name this diff --git a/src/ROCrate/ISAProfile/Sample.fs b/src/ROCrate/ISAProfile/Sample.fs index a607ce56..4604484a 100644 --- a/src/ROCrate/ISAProfile/Sample.fs +++ b/src/ROCrate/ISAProfile/Sample.fs @@ -12,7 +12,11 @@ type Sample( ?additionalProperty, ?derivesFrom ) as this = - inherit LDObject(id = id, schemaType = "bioschemas.org/Sample", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"bioschemas.org/Sample"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof name) name this diff --git a/src/ROCrate/ISAProfile/ScholarlyArticle.fs b/src/ROCrate/ISAProfile/ScholarlyArticle.fs index cb4905a5..be1e00b8 100644 --- a/src/ROCrate/ISAProfile/ScholarlyArticle.fs +++ b/src/ROCrate/ISAProfile/ScholarlyArticle.fs @@ -16,7 +16,11 @@ type ScholarlyArticle( ?disambiguatingDescription ) as this = - inherit LDObject(id = id, schemaType = "schema.org/ScholarlyArticle", ?additionalType = additionalType) + inherit LDObject( + id = id, + schemaType = ResizeArray[|"schema.org/ScholarlyArticle"|], + additionalType = defaultArg additionalType (ResizeArray[||]) + ) do DynObj.setProperty (nameof headline) headline this diff --git a/src/ROCrate/ISAProfile/Study.fs b/src/ROCrate/ISAProfile/Study.fs index 41bbd82e..14134592 100644 --- a/src/ROCrate/ISAProfile/Study.fs +++ b/src/ROCrate/ISAProfile/Study.fs @@ -20,7 +20,7 @@ type Study( ?headline, ?url ) as this = - inherit Dataset(id, "Study") + inherit Dataset(id = id, additionalType = ResizeArray[|"Study"|]) do DynObj.setProperty (nameof identifier) identifier this DynObj.setOptionalProperty (nameof about) about this diff --git a/src/ROCrate/LDObject.fs b/src/ROCrate/LDObject.fs index bf001ba7..fd2a48e2 100644 --- a/src/ROCrate/LDObject.fs +++ b/src/ROCrate/LDObject.fs @@ -9,18 +9,18 @@ type LDContext() = inherit DynamicObj() /// Base interface implemented by all explicitly known objects in our ROCrate profiles. type ILDObject = - abstract member SchemaType : string with get, set + abstract member SchemaType : ResizeArray with get, set abstract member Id: string - abstract member AdditionalType: string option with get, set + abstract member AdditionalType: ResizeArray with get, set /// Base class for all explicitly known objects in our ROCrate profiles to inherit from. /// Basically a DynamicObj that implements the ILDObject interface. [] -type LDObject(id:string, schemaType: string, ?additionalType) = +type LDObject(id: string, schemaType: ResizeArray, ?additionalType: ResizeArray) = inherit DynamicObj() let mutable schemaType = schemaType - let mutable additionalType = additionalType + let mutable additionalType = defaultArg additionalType (ResizeArray []) member this.Id with get() = id @@ -50,10 +50,54 @@ type LDObject(id:string, schemaType: string, ?additionalType) = static member setContext (context: LDContext) = fun (roc: #LDObject) -> roc.SetContext(context) - member this.TryGetContext() = DynObj.tryGetTypedPropertyValue("@context") this + member this.TryGetContext() = DynObj.tryGetTypedPropertyValue("@context") this static member tryGetContext () = fun (roc: #LDObject) -> roc.TryGetContext() member this.RemoveContext() = this.RemoveProperty("@context") - static member removeContext () = fun (roc: #LDObject) -> roc.RemoveContext() \ No newline at end of file + static member removeContext () = fun (roc: #LDObject) -> roc.RemoveContext() + + static member tryFromDynamicObj (dynObj: DynamicObj) = + + let original_id = DynObj.tryGetTypedPropertyValue "@id" dynObj + let original_type = DynObj.tryGetTypedPropertyValueAsResizeArray "@type" dynObj + match original_id, original_type with + | (Some id), (Some st)-> + // initialize with extracted static members only + let at = DynObj.tryGetTypedPropertyValueAsResizeArray "additionalType" dynObj + let roc = new LDObject(id = id, schemaType = st, ?additionalType = at) + + + // Currently commented out, as @context is set as a dynamic property + //match DynObj.tryGetTypedPropertyValue("@context") dynObj with + //| Some context -> roc.SetContext(context) + //| _ -> () + + // copy dynamic properties! + dynObj.DeepCopyPropertiesTo(roc, includeInstanceProperties = false) + + + // ----- Commented out as implementation has not been finalized ----- + //printfn "dynobj" + //dynObj.GetPropertyHelpers(true) + //|> Seq.iter (fun p -> printfn "isDynamic:%b, Name: %s" p.IsDynamic p.Name) + //printfn "roc" + //roc.GetPropertyHelpers(true) + //|> Seq.iter (fun p -> printfn "isDynamic:%b, Name: %s" p.IsDynamic p.Name) + //roc.TryGetDynamicPropertyHelper("@id").Value.RemoveValue() + //roc.TryGetDynamicPropertyHelper("@type").Value.RemoveValue() + //if at.IsSome then roc.TryGetDynamicPropertyHelper("additionalType").Value.RemoveValue() + + roc.GetPropertyHelpers(true) + |> Seq.iter (fun ph -> + if ph.IsDynamic && (ph.Name = "@id" || ph.Name = "@type" || ph.Name = "additionalType"(* || ph.Name = "id"*)) then + ph.RemoveValue(roc) + ) + + + + + Some roc + + | _ -> None diff --git a/tests/Json/LDObject.Tests.fs b/tests/Json/LDObject.Tests.fs index ad053dc7..6e552a7b 100644 --- a/tests/Json/LDObject.Tests.fs +++ b/tests/Json/LDObject.Tests.fs @@ -11,17 +11,21 @@ let private test_read = testList "Read" [ testCase "onlyIDAndType" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.onlyIDAndType) Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" testCase "onlyID" <| fun _ -> let f = fun _ -> LDObject.fromROCrateJsonString(GenericObjects.onlyID) |> ignore Expect.throws f "Should fail if Type is missing" testCase "onlyType" <| fun _ -> let f = fun _ -> LDObject.fromROCrateJsonString(GenericObjects.onlyType) |> ignore Expect.throws f "Should fail if ID is missing" + testCase "twoTypesAndID" <| fun _ -> + let json = LDObject.fromROCrateJsonString(GenericObjects.twoTypesAndID) + Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"; "MySecondType"] "type was not parsed correctly" testCase "withStringFields" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withStringFields) Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let name = Expect.wantSome (DynObj.tryGetTypedPropertyValue "name" json) "field name was not parsed" Expect.equal name "MyName" "field name was not parsed correctly" let description = Expect.wantSome (DynObj.tryGetTypedPropertyValue "description" json) "field description was not parsed" @@ -29,7 +33,7 @@ let private test_read = testList "Read" [ testCase "withIntFields" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withIntFields) Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let number = Expect.wantSome (DynObj.tryGetTypedPropertyValue "number" json) "field number was not parsed" Expect.equal number 42 "field number was not parsed correctly" let anotherNumber = Expect.wantSome (DynObj.tryGetTypedPropertyValue "anotherNumber" json) "field anotherNumber was not parsed" @@ -37,7 +41,7 @@ let private test_read = testList "Read" [ testCase "withStringArray" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withStringArray) Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let names = Expect.wantSome (DynObj.tryGetTypedPropertyValue> "names" json) "field names was not parsed" Expect.equal names.Count 2 "ResizeArray length is wrong" Expect.equal names.[0] "MyName" "First name was not parsed correctly" @@ -45,75 +49,154 @@ let private test_read = testList "Read" [ testCase "withNestedObject" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withNestedObject) Expect.equal json.Id "OuterIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let nested = Expect.wantSome (DynObj.tryGetTypedPropertyValue "nested" json) "field nested was not parsed" Expect.equal nested.Id "MyIdentifier" "nested id was not parsed correctly" - Expect.equal nested.SchemaType "MyType" "nested type was not parsed correctly" + Expect.sequenceEqual nested.SchemaType ResizeArray["MyType"] "nested type was not parsed correctly" testCase "withObjectArray" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withObjectArray) Expect.equal json.Id "OuterIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let nested = Expect.wantSome (DynObj.tryGetTypedPropertyValue> "nested" json) "field nested was not parsed" Expect.equal nested.Count 2 "ResizeArray length is wrong" let o1 = nested.[0] :?> LDObject Expect.equal o1.Id "MyIdentifier" "First nested id was not parsed correctly" - Expect.equal o1.SchemaType "MyType" "First nested type was not parsed correctly" + Expect.sequenceEqual o1.SchemaType ResizeArray["MyType"] "First nested type was not parsed correctly" let o2 = nested.[1] :?> LDObject Expect.equal o2.Id "MyIdentifier" "Second nested id was not parsed correctly" - Expect.equal o2.SchemaType "MyType" "Second nested type was not parsed correctly" + Expect.sequenceEqual o2.SchemaType ResizeArray["MyType"] "Second nested type was not parsed correctly" testCase "withMixedArray" <| fun _ -> let json = LDObject.fromROCrateJsonString(GenericObjects.withMixedArray) Expect.equal json.Id "OuterIdentifier" "id was not parsed correctly" - Expect.equal json.SchemaType "MyType" "type was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" let nested = Expect.wantSome (DynObj.tryGetTypedPropertyValue> "nested" json) "field nested was not parsed" Expect.equal nested.Count 3 "ResizeArray length is wrong" let o1 = nested.[0] :?> LDObject Expect.equal o1.Id "MyIdentifier" "First nested id of object was not parsed correctly" - Expect.equal o1.SchemaType "MyType" "First nested type of object was not parsed correctly" + Expect.sequenceEqual o1.SchemaType ResizeArray["MyType"] "First nested type of object was not parsed correctly" let o2 = nested.[1] :?> string Expect.equal o2 "Value2" "Second nested string was not parsed correctly" let o3 = nested.[2] :?> int Expect.equal o3 42 "Third nested int was not parsed correctly" + testCase "withAdditionalTypeString" <| fun _ -> + let json = LDObject.fromROCrateJsonString(GenericObjects.withAdditionalTypeString) + Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" + Expect.sequenceEqual json.AdditionalType ResizeArray["additionalType"] "additionalType was not parsed correctly" + testCase "withAdditionalTypeArray" <| fun _ -> + let json = LDObject.fromROCrateJsonString(GenericObjects.withAdditionalTypeArray) + Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" + Expect.sequenceEqual json.AdditionalType ResizeArray["additionalType"] "additionalType was not parsed correctly" + testCase "withAddtionalTypeArrayMultipleEntries" <| fun _ -> + let json = LDObject.fromROCrateJsonString(GenericObjects.withAddtionalTypeArrayMultipleEntries) + Expect.equal json.Id "MyIdentifier" "id was not parsed correctly" + Expect.sequenceEqual json.SchemaType ResizeArray["MyType"] "type was not parsed correctly" + Expect.sequenceEqual json.AdditionalType ResizeArray["additionalType1"; "additionalType2"] "additionalType was not parsed correctly" ] let test_write = testList "write" [ + // The tests suffixed with 'NoTypeArray' are not real roundtrips, as we parse string OR array fields but always write arrays for the @type field. testCase "onlyIDAndType" <| fun _ -> let json = GenericObjects.onlyIDAndType let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "onlyIDAndTypeNoTypeArray" <| fun _ -> + let json = GenericObjects.onlyIDAndTypeNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.onlyIDAndType "Output string is not correct" + + testCase "twoTypesAndID" <| fun _ -> + let json = GenericObjects.twoTypesAndID + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output json "Output string is not correct" + testCase "withStringFields" <| fun _ -> let json = GenericObjects.withStringFields let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "withStringFieldsNoTypeArray" <| fun _ -> + let json = GenericObjects.withStringFieldsNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withStringFields "Output string is not correct" + testCase "withIntFields" <| fun _ -> let json = GenericObjects.withIntFields let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "withIntFieldsNoTypeArray" <| fun _ -> + let json = GenericObjects.withIntFieldsNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withIntFields "Output string is not correct" + testCase "withStringArray" <| fun _ -> let json = GenericObjects.withStringArray let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "withStringArrayNoTypeArray" <| fun _ -> + let json = GenericObjects.withStringArrayNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withStringArray "Output string is not correct" + testCase "withNestedObject" <| fun _ -> let json = GenericObjects.withNestedObject let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "withNestedObjectNoTypeArray" <| fun _ -> + let json = GenericObjects.withNestedObjectNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withNestedObject "Output string is not correct" + testCase "withObjectArray" <| fun _ -> let json = GenericObjects.withObjectArray let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" + testCase "withObjectArrayNoTypeArray" <| fun _ -> + let json = GenericObjects.withObjectArrayNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withObjectArray "Output string is not correct" + testCase "withMixedArray" <| fun _ -> let json = GenericObjects.withMixedArray let object = LDObject.fromROCrateJsonString(json) let output = LDObject.toROCrateJsonString() object Expect.stringEqual output json "Output string is not correct" - + testCase "withMixedArrayNoTypeArray" <| fun _ -> + let json = GenericObjects.withMixedArrayNoTypeArray + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output GenericObjects.withMixedArray "Output string is not correct" + + testCase "withAddtionalTypeArray" <| fun _ -> + let json = GenericObjects.withAdditionalTypeArray + let jsonOut = GenericObjects.withAdditionalTypeString + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output jsonOut "Output string is not correct" + testCase "withAddtionalTypeArrayMultipleEntries" <| fun _ -> + let json = GenericObjects.withAddtionalTypeArrayMultipleEntries + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output json "Output string is not correct" + testCase "withAddtionalTypeString" <| fun _ -> + let json = GenericObjects.withAdditionalTypeString + let object = LDObject.fromROCrateJsonString(json) + let output = LDObject.toROCrateJsonString() object + Expect.stringEqual output json "Output string is not correct" ] let main = testList "LDObject" [ diff --git a/tests/ROCrate/Common.fs b/tests/ROCrate/Common.fs index 0c56cc5f..2a89cb2c 100644 --- a/tests/ROCrate/Common.fs +++ b/tests/ROCrate/Common.fs @@ -11,11 +11,28 @@ module Expect = Expect.equal roc.Id expectedId "object did not contain correct @id" let inline LDObjectHasType (expectedType:string) (roc:#LDObject) = - Expect.equal roc.SchemaType expectedType "object did not contain correct @type" + Expect.containsAll + roc.SchemaType + [expectedType] + "object did not contain correct @type" + + let inline LDObjectHasTypes (expectedTypes:seq) (roc:#LDObject) = + Expect.containsAll + roc.SchemaType + expectedTypes + "object did not contain correct @types" let inline LDObjectHasAdditionalType (expectedAdditionalType:string) (roc:#LDObject) = - Expect.isSome roc.AdditionalType "additionalType was None" - Expect.equal roc.AdditionalType (Some expectedAdditionalType) "object did not contain correct additionalType" + Expect.containsAll + roc.AdditionalType + [expectedAdditionalType] + "object did not contain correct additionalType" + + let inline LDObjectHasAdditionalTypes (expectedAdditionalTypes:seq) (roc:#LDObject) = + Expect.containsAll + roc.AdditionalType + expectedAdditionalTypes + "object did not contain correct additionalTypes" let inline LDObjectHasDynamicProperty (expectedPropertyName:string) (expectedPropertyValue:'P) (roc:#LDObject) = Expect.isSome (roc.TryGetDynamicPropertyHelper(expectedPropertyName)) $"object did not contain the dynamic property '{expectedPropertyName}'" @@ -25,14 +42,14 @@ module Expect = $"property value of '{expectedPropertyName}' was not correct" let inline LDObjectHasStaticProperty (expectedPropertyName:string) (expectedPropertyValue:'P) (roc:#LDObject) = - Expect.isSome (roc.TryGetDynamicPropertyHelper(expectedPropertyName)) $"object did not contain the dynamic property '{expectedPropertyName}'" + Expect.isSome (roc.TryGetStaticPropertyHelper(expectedPropertyName)) $"object did not contain the static property '{expectedPropertyName}'" Expect.equal (DynObj.tryGetTypedPropertyValue<'P> expectedPropertyName roc) (Some expectedPropertyValue) $"property value of '{expectedPropertyName}' was not correct" - let inline LDObjectHasExpectedInterfaceMembers (expectedType:string) (expectedId:string) (expectedAdditionalType:string option) (roc:#LDObject) = + let inline LDObjectHasExpectedInterfaceMembers (expectedTypes: seq) (expectedId:string) (expectedAdditionalTypes: seq) (roc:#LDObject) = let interfacerino = roc :> ILDObject - Expect.equal interfacerino.SchemaType expectedType "object did not contain correct @type via interface access" + Expect.sequenceEqual interfacerino.SchemaType expectedTypes "object did not contain correct @types via interface access" Expect.equal interfacerino.Id expectedId "object did not contain correct @id via interface access" - Expect.equal interfacerino.AdditionalType expectedAdditionalType "object did not contain correct additionalType via interface access" + Expect.sequenceEqual interfacerino.AdditionalType expectedAdditionalTypes "object did not contain correct additionalTypes via interface access" diff --git a/tests/ROCrate/ISAProfile/Assay.Tests.fs b/tests/ROCrate/ISAProfile/Assay.Tests.fs index 70eb7a86..5d60761d 100644 --- a/tests/ROCrate/ISAProfile/Assay.Tests.fs +++ b/tests/ROCrate/ISAProfile/Assay.Tests.fs @@ -48,8 +48,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "assay_mandatory_properties_id" (Some "Assay") mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "assay_all_properties_id" (Some "Assay") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "assay_mandatory_properties_id" [|"Assay"|] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "assay_all_properties_id" [|"Assay"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Data.Tests.fs b/tests/ROCrate/ISAProfile/Data.Tests.fs index bbeb6716..45fae9f3 100644 --- a/tests/ROCrate/ISAProfile/Data.Tests.fs +++ b/tests/ROCrate/ISAProfile/Data.Tests.fs @@ -14,7 +14,7 @@ let mandatory_properties = Data( let all_properties = Data( id = "data_all_properties_id", name = "name", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), comment = "comment", encodingFormat = "encodingFormat", disambiguatingDescription = "disambiguatingDescription" @@ -38,8 +38,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/MediaObject" "data_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/MediaObject" "data_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/MediaObject"|] "data_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/MediaObject"|] "data_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Dataset.Tests.fs b/tests/ROCrate/ISAProfile/Dataset.Tests.fs index f4468679..519a7aee 100644 --- a/tests/ROCrate/ISAProfile/Dataset.Tests.fs +++ b/tests/ROCrate/ISAProfile/Dataset.Tests.fs @@ -7,7 +7,7 @@ open TestingUtils open Common let mandatory_properties = Dataset("dataset_mandatory_properties_id") -let all_properties = Dataset("dataset_all_properties_id", additionalType = "additionalType") +let all_properties = Dataset("dataset_all_properties_id", additionalType = ResizeArray([|"additionalType"|])) let tests_profile_object_is_valid = testList "constructed properties" [ testList "mandatory properties" [ @@ -22,8 +22,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "dataset_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "dataset_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "dataset_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "dataset_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Investigation.Tests.fs b/tests/ROCrate/ISAProfile/Investigation.Tests.fs index 8e051460..b42f6c65 100644 --- a/tests/ROCrate/ISAProfile/Investigation.Tests.fs +++ b/tests/ROCrate/ISAProfile/Investigation.Tests.fs @@ -54,8 +54,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "investigation_mandatory_properties_id" (Some "Investigation") mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "investigation_all_properties_id" (Some "Investigation") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "investigation_mandatory_properties_id" [|"Investigation"|] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "investigation_all_properties_id" [|"Investigation"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/LabProcess.tests.fs b/tests/ROCrate/ISAProfile/LabProcess.tests.fs index 23971baf..6732ea5c 100644 --- a/tests/ROCrate/ISAProfile/LabProcess.tests.fs +++ b/tests/ROCrate/ISAProfile/LabProcess.tests.fs @@ -20,7 +20,7 @@ let all_properties = LabProcess( agent = "agent", object = "object", result = "result", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), executesLabProtocol = "executesLabProtocol", parameterValue = "parameterValue", endTime = "endTime", @@ -53,8 +53,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/LabProcess" "labprocess_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/LabProcess" "labprocess_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/LabProcess"|] "labprocess_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/LabProcess"|] "labprocess_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/LabProtocol.Tests.fs b/tests/ROCrate/ISAProfile/LabProtocol.Tests.fs index 588036c0..1c88e3eb 100644 --- a/tests/ROCrate/ISAProfile/LabProtocol.Tests.fs +++ b/tests/ROCrate/ISAProfile/LabProtocol.Tests.fs @@ -12,7 +12,7 @@ let mandatory_properties = LabProtocol( let all_properties = LabProtocol( id = "labprotocol_all_properties_id", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), name = "name", intendedUse = "intendedUse", description = "description", @@ -46,8 +46,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/LabProtocol" "labprotocol_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/LabProtocol" "labprotocol_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/LabProtocol"|] "labprotocol_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/LabProtocol"|] "labprotocol_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Person.Tests.fs b/tests/ROCrate/ISAProfile/Person.Tests.fs index 107dfb28..70bc372e 100644 --- a/tests/ROCrate/ISAProfile/Person.Tests.fs +++ b/tests/ROCrate/ISAProfile/Person.Tests.fs @@ -14,7 +14,7 @@ let mandatory_properties = Person( let all_properties = Person( id = "person_all_properties_id", givenName = "givenName", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), familyName = "familyName", email = "email", identifier = "identifier", @@ -52,8 +52,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Person" "person_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Person" "person_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Person"|] "person_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Person"|] "person_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/PropertyValue.Tests.fs b/tests/ROCrate/ISAProfile/PropertyValue.Tests.fs index c44ec118..016ca86c 100644 --- a/tests/ROCrate/ISAProfile/PropertyValue.Tests.fs +++ b/tests/ROCrate/ISAProfile/PropertyValue.Tests.fs @@ -20,7 +20,7 @@ let all_properties = PropertyValue( unitCode = "unitCode", unitText = "unitText", valueReference = "valueReference", - additionalType = "additionalType" + additionalType = ResizeArray([|"additionalType"|]) ) let tests_profile_object_is_valid = testList "constructed properties" [ @@ -44,8 +44,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/PropertyValue" "propertyvalue_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/PropertyValue" "propertyvalue_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/PropertyValue"|] "propertyvalue_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/PropertyValue"|] "propertyvalue_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Sample.tests.fs b/tests/ROCrate/ISAProfile/Sample.tests.fs index 659cb47d..d5f26f31 100644 --- a/tests/ROCrate/ISAProfile/Sample.tests.fs +++ b/tests/ROCrate/ISAProfile/Sample.tests.fs @@ -14,7 +14,7 @@ let mandatory_properties = Sample( let all_properties = Sample( id = "sample_all_properties_id", name = "name", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), additionalProperty = "additionalProperty", derivesFrom = "derivesFrom" ) @@ -36,8 +36,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/Sample" "sample_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "bioschemas.org/Sample" "sample_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/Sample"|] "sample_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"bioschemas.org/Sample"|] "sample_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/ScholarlyArticle.Tests.fs b/tests/ROCrate/ISAProfile/ScholarlyArticle.Tests.fs index ea2c1168..13a1d12f 100644 --- a/tests/ROCrate/ISAProfile/ScholarlyArticle.Tests.fs +++ b/tests/ROCrate/ISAProfile/ScholarlyArticle.Tests.fs @@ -16,7 +16,7 @@ let all_properties = ScholarlyArticle( id = "scholarlyarticle_all_properties_id", headline = "headline", identifier = "identifier", - additionalType = "additionalType", + additionalType = ResizeArray([|"additionalType"|]), author = "author", url = "url", creativeWorkStatus = "creativeWorkStatus", @@ -44,8 +44,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/ScholarlyArticle" "scholarlyarticle_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/ScholarlyArticle" "scholarlyarticle_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/ScholarlyArticle"|] "scholarlyarticle_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/ScholarlyArticle"|] "scholarlyarticle_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/ISAProfile/Study.Tests.fs b/tests/ROCrate/ISAProfile/Study.Tests.fs index b987aef2..352b445b 100644 --- a/tests/ROCrate/ISAProfile/Study.Tests.fs +++ b/tests/ROCrate/ISAProfile/Study.Tests.fs @@ -54,8 +54,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "study_mandatory_properties_id" (Some "Study") mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "schema.org/Dataset" "study_all_properties_id" (Some "Study") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "study_mandatory_properties_id" [|"Study"|] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"schema.org/Dataset"|] "study_all_properties_id" [|"Study"|] all_properties ] let tests_dynamic_members = testSequenced ( diff --git a/tests/ROCrate/LDObject.Tests.fs b/tests/ROCrate/LDObject.Tests.fs index 658c7e1d..6d15e6d2 100644 --- a/tests/ROCrate/LDObject.Tests.fs +++ b/tests/ROCrate/LDObject.Tests.fs @@ -6,8 +6,19 @@ open DynamicObj open TestingUtils open Common -let mandatory_properties = LDObject("LDObject_mandatory_properties_id", "someType") -let all_properties = LDObject("LDObject_all_properties_id", "someType", additionalType = "additionalType") +let context = + new LDContext() + |> DynObj.withProperty "more" "context" + +let mandatory_properties = LDObject("LDObject_mandatory_properties_id", ResizeArray[|"someType"|]) +let mandatory_properties_with_context = + LDObject("LDObject_mandatory_properties_id", ResizeArray[|"someType"|]) + |> DynObj.withProperty "@context" context + +let all_properties = LDObject("LDObject_all_properties_id", ResizeArray[|"someType"|], additionalType = ResizeArray[|"additionalType"|]) +let all_properties_with_context = + LDObject("LDObject_all_properties_id", ResizeArray[|"someType"|], additionalType = ResizeArray[|"additionalType"|]) + |> DynObj.withProperty "@context" (context.DeepCopyProperties()) let tests_profile_object_is_valid = testList "constructed properties" [ testList "mandatory properties" [ @@ -22,8 +33,8 @@ let tests_profile_object_is_valid = testList "constructed properties" [ ] let tests_interface_members = testList "interface members" [ - testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "someType" "LDObject_mandatory_properties_id" None mandatory_properties - testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers "someType" "LDObject_all_properties_id" (Some "additionalType") all_properties + testCase "mandatoryProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"someType"|] "LDObject_mandatory_properties_id" [||] mandatory_properties + testCase "allProperties" <| fun _ -> Expect.LDObjectHasExpectedInterfaceMembers [|"someType"|] "LDObject_all_properties_id" [|"additionalType"|] all_properties ] let tests_dynamic_members = testSequenced ( @@ -58,19 +69,50 @@ let tests_instance_methods = testSequenced ( let tests_static_methods = testSequenced ( testList "static methods" [ + testList "context" [ + let context = new LDContext() + context.SetProperty("more", "context") - let context = new LDContext() - context.SetProperty("more", "context") + testCase "can set context" <| fun _ -> + LDObject.setContext context mandatory_properties + Expect.LDObjectHasDynamicProperty "@context" context mandatory_properties + testCase "can get context" <| fun _ -> + let ctx = LDObject.tryGetContext() mandatory_properties + Expect.equal ctx (Some context) "context was not set correctly" + testCase "can remove context" <| fun _ -> + LDObject.removeContext() mandatory_properties |> ignore + Expect.isNone (DynObj.tryGetTypedPropertyValue "@context" mandatory_properties) "context was not removed correctly" + ] + testList "tryFromDynamicObj" [ + let compatibleDynObj = + let tmp = DynamicObj() + tmp + |> DynObj.withProperty "@type" "someType" + |> DynObj.withProperty "@id" "LDObject_all_properties_id" + |> DynObj.withProperty "additionalType" "additionalType" - testCase "can set context" <| fun _ -> - LDObject.setContext context mandatory_properties - Expect.LDObjectHasDynamicProperty "@context" context mandatory_properties - testCase "can get context" <| fun _ -> - let ctx = LDObject.tryGetContext() mandatory_properties - Expect.equal ctx (Some context) "context was not set correctly" - testCase "can remove context" <| fun _ -> - LDObject.removeContext() mandatory_properties |> ignore - Expect.isNone (DynObj.tryGetTypedPropertyValue "@context" mandatory_properties) "context was not removed correctly" + let compatibleDynObjWithContext = + let tmp = DynamicObj() + tmp + |> DynObj.withProperty "@type" "someType" + |> DynObj.withProperty "@id" "LDObject_all_properties_id" + |> DynObj.withProperty "additionalType" "additionalType" + |> DynObj.withProperty "@context" context + + let incompatibleDynObj = + let tmp = DynamicObj() + tmp + |> DynObj.withProperty "@type" "someType" + + testCase "can convert compatible DynObj to LDObject" <| fun _ -> + let roc = Expect.wantSome (LDObject.tryFromDynamicObj compatibleDynObj) "LDObject.tryFromDynamicObj did not return Some" + Expect.equal roc all_properties "LDObject was not created correctly from compatible DynamicObj" + testCase "can convert compatible DynObj with context to LDObject" <| fun _ -> + let roc = Expect.wantSome (LDObject.tryFromDynamicObj compatibleDynObjWithContext) "LDObject.tryFromDynamicObj did not return Some" + Expect.equal roc all_properties_with_context "LDObject was not created correctly from compatible DynamicObj" + testCase "cannot convert incompatible DynObj to LDObject" <| fun _ -> + Expect.isNone (LDObject.tryFromDynamicObj incompatibleDynObj) "LDObject.tryFromDynamicObj did not return None" + ] ] ) diff --git a/tests/TestingUtils/TestObjects.Json/ROCrate.fs b/tests/TestingUtils/TestObjects.Json/ROCrate.fs index 4d403ca6..daf9c8fe 100644 --- a/tests/TestingUtils/TestObjects.Json/ROCrate.fs +++ b/tests/TestingUtils/TestObjects.Json/ROCrate.fs @@ -208,6 +208,12 @@ module GenericObjects = "@id": "MyIdentifier", "@type": "MyType" }""" + + let onlyIDAndTypeNoTypeArray = + """{ + "@id": "MyIdentifier", + "@type": "MyType" + }""" let onlyID = """{ @@ -219,6 +225,17 @@ module GenericObjects = "@type": "MyType" }""" + let twoTypesAndID = + """{ + "@id": "MyIdentifier", + "@type": ["MyType" , "MySecondType"] + }""" + + let onlyTypeNoTypeArray = + """{ + "@type": "MyType" + }""" + let withStringFields = """{ "@id": "MyIdentifier", @@ -227,6 +244,14 @@ module GenericObjects = "description": "MyDescription" }""" + let withStringFieldsNoTypeArray = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "name": "MyName", + "description": "MyDescription" + }""" + let withIntFields = """{ "@id": "MyIdentifier", @@ -234,6 +259,14 @@ module GenericObjects = "number": 42, "anotherNumber": 1337 }""" + + let withIntFieldsNoTypeArray = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "number": 42, + "anotherNumber": 1337 + }""" let withStringArray = """{ @@ -242,6 +275,13 @@ module GenericObjects = "names": ["MyName", "MySecondName"] }""" + let withStringArrayNoTypeArray = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "names": ["MyName", "MySecondName"] + }""" + let withNestedObject = sprintf """{ "@id": "OuterIdentifier", @@ -249,6 +289,13 @@ module GenericObjects = "nested": %s }""" onlyIDAndType + let withNestedObjectNoTypeArray = + sprintf """{ + "@id": "OuterIdentifier", + "@type": "MyType", + "nested": %s + }""" onlyIDAndTypeNoTypeArray + let withObjectArray = sprintf """{ "@id": "OuterIdentifier", @@ -256,9 +303,43 @@ module GenericObjects = "nested": [%s, %s] }""" onlyIDAndType onlyIDAndType + let withObjectArrayNoTypeArray = + sprintf """{ + "@id": "OuterIdentifier", + "@type": "MyType", + "nested": [%s, %s] + }""" onlyIDAndTypeNoTypeArray onlyIDAndTypeNoTypeArray + let withMixedArray = sprintf """{ "@id": "OuterIdentifier", "@type": "MyType", "nested": [%s, "Value2", 42] - }""" onlyIDAndType \ No newline at end of file + }""" onlyIDAndType + + let withMixedArrayNoTypeArray = + sprintf """{ + "@id": "OuterIdentifier", + "@type": "MyType", + "nested": [%s, "Value2", 42] + }""" onlyIDAndTypeNoTypeArray + + let withAdditionalTypeString = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "additionalType": "additionalType" + }""" + + let withAdditionalTypeArray = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "additionalType": ["additionalType"] + }""" + let withAddtionalTypeArrayMultipleEntries = + """{ + "@id": "MyIdentifier", + "@type": "MyType", + "additionalType": ["additionalType1", "additionalType2"] + }""" \ No newline at end of file