Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve LDObject, add ISA model API #478

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions build/ProjectInfo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 16 additions & 19 deletions build/TestTasks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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"

Expand All @@ -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"
)
Expand All @@ -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.
Expand Down
6 changes: 2 additions & 4 deletions src/Json/Decode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@ module Decode =
decoder.Decode(helpers,value)
}



let resizeArray (decoder: Decoder<'value>) : Decoder<ResizeArray<'value>> =
let resizeArrayOrSingleton (decoder: Decoder<'value>) : Decoder<ResizeArray<'value>> =
{ new Decoder<ResizeArray<'value>> with
member _.Decode(helpers, value) =
if helpers.isArray value then
Expand Down Expand Up @@ -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<System.DateTime> =
Expand Down
32 changes: 14 additions & 18 deletions src/Json/LDObject.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ open Thoth.Json.Core
open DynamicObj

module rec LDObject =

#if !FABLE_COMPILER
let (|SomeObj|_|) =
// create generalized option type
Expand Down Expand Up @@ -45,21 +44,17 @@ 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

)
|> Seq.append [
"@id", Encode.string obj.Id
"@type", Encode.string obj.SchemaType
if obj.AdditionalType.IsSome then
"additionalType", Encode.string obj.AdditionalType.Value

[
yield "@id", Encode.string obj.Id |> Some
yield "@type", Encode.seq (obj.SchemaType |> Seq.map Encode.string) |> Some
yield Encode.tryIncludeSeq "additionalType" Encode.string obj.AdditionalType
for kv in (obj.GetProperties true) do
let l = kv.Key.ToLower()
if l <> "id" && l <> "schematype" && l <> "additionaltype" then
yield kv.Key, Some (genericEncoder kv.Value)
]
|> Encode.choose
|> Encode.object

/// Returns a decoder
Expand All @@ -75,11 +70,12 @@ 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 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 <> "additionalType" then
o.SetProperty(property,get.Required.Field property (decode(false)))
o
let result = builder getters
Expand Down
2 changes: 1 addition & 1 deletion src/ROCrate/ArcROCrateMetadata.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion src/ROCrate/ISAProfile/Assay.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/Data.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
10 changes: 7 additions & 3 deletions src/ROCrate/ISAProfile/Dataset.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ namespace ARCtrl.ROCrate

open DynamicObj
open Fable.Core

///
[<AttachMembers>]
type Dataset (id: string, ?additionalType: string) =
inherit LDObject(id = id, schemaType = "schema.org/Dataset", ?additionalType = additionalType)
type Dataset (id: string, ?additionalType: ResizeArray<string>) =
inherit LDObject(
id = id,
schemaType = ResizeArray[|"schema.org/Dataset"|],
additionalType = defaultArg additionalType (ResizeArray[||])
)
2 changes: 1 addition & 1 deletion src/ROCrate/ISAProfile/Investigation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/LabProcess.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/LabProtocol.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/Person.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/PropertyValue.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/Sample.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 5 additions & 1 deletion src/ROCrate/ISAProfile/ScholarlyArticle.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ROCrate/ISAProfile/Study.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 24 additions & 5 deletions src/ROCrate/LDObject.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> with get, set
abstract member Id: string
abstract member AdditionalType: string option with get, set
abstract member AdditionalType: ResizeArray<string> 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.
[<AttachMembers>]
type LDObject(id:string, schemaType: string, ?additionalType) =
type LDObject(id: string, schemaType: ResizeArray<string>, ?additionalType: ResizeArray<string>) =
inherit DynamicObj()

let mutable schemaType = schemaType
let mutable additionalType = additionalType
let mutable additionalType = defaultArg additionalType (ResizeArray [])

member this.Id
with get() = id
Expand Down Expand Up @@ -56,4 +56,23 @@ type LDObject(id:string, schemaType: string, ?additionalType) =

member this.RemoveContext() = this.RemoveProperty("@context")

static member removeContext () = fun (roc: #LDObject) -> roc.RemoveContext()
static member removeContext () = fun (roc: #LDObject) -> roc.RemoveContext()

static member tryFromDynamicObj (dynObj: DynamicObj) =
match
DynObj.tryGetTypedPropertyValue<ResizeArray<string>>("@type") dynObj,
DynObj.tryGetTypedPropertyValue<string>("@id") dynObj,
DynObj.tryGetTypedPropertyValue<ResizeArray<string>>("additionalType") dynObj
with
| (Some st), (Some id), (Some at) ->
// initialize with extracted static members only
let roc = new LDObject(id = id, schemaType = st, additionalType = at)

// copy dynamic properties!
match DynObj.tryGetTypedPropertyValue<LDContext>("@context") dynObj with
| Some context -> roc.SetContext(context)
| _ -> ()
dynObj.CopyDynamicPropertiesTo(roc)
Some roc
| _ -> None

Loading
Loading