Skip to content

Commit

Permalink
Merge pull request #463 from nfdi4plants/templateCopy
Browse files Browse the repository at this point in the history
Template copy and test+fix deepcopying of ArcTable
  • Loading branch information
HLWeil authored Oct 24, 2024
2 parents 924a87d + 68fc64e commit 291198e
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 12 deletions.
5 changes: 1 addition & 4 deletions src/Core/ArcTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,7 @@ type ArcAssay(identifier: string, ?measurementType : OntologyAnnotation, ?techno
assay

member this.Copy() : ArcAssay =
let nextTables = ResizeArray()
for table in this.Tables do
let copy = table.Copy()
nextTables.Add(copy)
let nextTables = this.Tables |> ResizeArray.map (fun c -> c.Copy())
let nextComments = this.Comments |> ResizeArray.map (fun c -> c.Copy())
let nextDataMap = this.DataMap |> Option.map (fun d -> d.Copy())
let nextPerformers = this.Performers |> ResizeArray.map (fun c -> c.Copy())
Expand Down
13 changes: 10 additions & 3 deletions src/Core/Table/ArcTable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,18 @@ type ArcTable(name: string, headers: ResizeArray<CompositeHeader>, values: Syste
member this.Columns
with get() = [|for i = 0 to this.ColumnCount - 1 do this.GetColumn(i)|]

member this.Copy() : ArcTable =
member this.Copy() : ArcTable =
let nextHeaders = this.Headers |> ResizeArray.map (fun h -> h.Copy())
let nextValues = Dictionary<int*int,CompositeCell>()
this.Values.Keys
|> Seq.iter (fun (ci,ri) ->
let newCell = this.Values.[ci,ri].Copy()
nextValues.Add((ci,ri),newCell)
)
ArcTable.create(
this.Name,
ResizeArray(this.Headers),
Dictionary(this.Values)
nextHeaders,
nextValues
)

/// Returns a cell at given position if it exists, else returns None.
Expand Down
11 changes: 10 additions & 1 deletion src/Core/Table/CompositeHeader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ type CompositeHeader =
| ProtocolType | ProtocolREF | ProtocolDescription | ProtocolUri | ProtocolVersion | Performer | Date | Input _ | Output _ -> true
| _ -> false

member this.Copy() =
match this with
| Parameter oa -> Parameter (oa.Copy())
| Factor oa -> Factor (oa.Copy())
| Characteristic oa -> Characteristic (oa.Copy())
| Component oa -> Component (oa.Copy())
| _ -> this


#if FABLE_COMPILER

[<CompiledName("component")>]
Expand Down Expand Up @@ -465,4 +474,4 @@ type CompositeHeader =

static member comment(s:string) = Comment s

#endif
#endif
19 changes: 18 additions & 1 deletion src/Core/Template.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ARCtrl
namespace ARCtrl

open Fable.Core
open ARCtrl.Helper
Expand Down Expand Up @@ -68,6 +68,23 @@ type Template(id: System.Guid, table: ArcTable, ?name: string, ?description, ?or
member this.StructurallyEquals (other: Template) =
this.GetHashCode() = other.GetHashCode()

member this.Copy() : Template =
let nextAuthors = this.Authors |> ResizeArray.map (fun c -> c.Copy())
let nextRepos = this.EndpointRepositories |> ResizeArray.map (fun c -> c.Copy())
let nextTags = this.Tags |> ResizeArray.map (fun c -> c.Copy())
Template.create(
this.Id,
this.Table.Copy(),
this.Name,
this.Description,
this.Organisation,
this.Version,
nextAuthors,
nextRepos,
nextTags,
this.LastUpdated
)

// custom check
override this.Equals other =
match other with
Expand Down
130 changes: 128 additions & 2 deletions tests/Core/ArcTable.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ let private tests_AddColumn_Mutable =
]

/// Exemplary tests to check non mutable implementation of mutability bases member function.
let private tests_addColumn_Copy =
let private tests_addColumn =
let header_input = CompositeHeader.Input IOType.Source
let header_chara = CompositeHeader.Characteristic oa_species
let createCells_chara (count) = Array.init count (fun _ -> CompositeCell.createTerm oa_chlamy)
Expand Down Expand Up @@ -2539,6 +2539,131 @@ let private tests_equality = testList "equality" [
]
]

let private tests_copy = testList "Copy" [
testCase "DefaultEquality"<| fun _ ->
let table = create_testTable()
let copy = table.Copy()
Expect.equal table copy "Tables should be equal"
testCase "StructuralEquality" <| fun _ ->
let table = create_testTable()
let copy = table.Copy()
let equals = table.StructurallyEquals(copy)
Expect.isTrue equals "Structural equality should be true"
testCase "ReferenceEquality" <| fun _ ->
let table = create_testTable()
let copy = table.Copy()
let equals = table.ReferenceEquals(copy)
Expect.isFalse equals "Reference equality should be false"
testCase "UpdateInputHeader" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(CompositeHeader.Input IOType.Sample)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.UpdateHeader(0,CompositeHeader.Input IOType.Data)
Expect.equal (table.Headers.[0]) (CompositeHeader.Input IOType.Sample) "Header of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateParameterHeader" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(CompositeHeader.Parameter (OntologyAnnotation("OldAnnotation")))
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.UpdateHeader(0,CompositeHeader.Parameter (OntologyAnnotation("NewAnnotation")))
Expect.equal (table.Headers.[0]) (CompositeHeader.Parameter (OntologyAnnotation("OldAnnotation"))) "Header of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateAnnotationOfParameterHeader" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(CompositeHeader.Parameter (OntologyAnnotation("OldAnnotation")))
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
match copy.Headers.[0] with
| CompositeHeader.Parameter oa -> oa.Name <- Some "NewAnnotation"
| _ -> Expect.isTrue false "Header not parameter?"
Expect.equal (table.Headers.[0]) (CompositeHeader.Parameter (OntologyAnnotation("OldAnnotation"))) "Header of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateFreetextCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Input IOType.Sample,
[|CompositeCell.FreeText "OldFreetext"|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.SetCellAt(0,0,CompositeCell.FreeText "NewFreetext")
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.FreeText "OldFreetext") "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateDataCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Input IOType.Data,
[|CompositeCell.Data (Data(name = "OldData"))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.SetCellAt(0,0,CompositeCell.Data (Data(name = "NewData")))
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.Data (Data(name = "OldData"))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateNameOfDataCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Input IOType.Data,
[|CompositeCell.Data (Data(name = "OldData"))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
match copy.GetCellAt(0,0) with
| CompositeCell.Data d -> d.Name <- Some "NewData"
| _ -> Expect.isTrue false "Cell not data?"
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.Data (Data(name = "OldData"))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateTermCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Parameter (OntologyAnnotation("MyParameter")),
[|CompositeCell.createTerm (OntologyAnnotation("OldAnnotation"))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.SetCellAt(0,0,CompositeCell.createTerm (OntologyAnnotation("NewAnnotation")))
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.createTerm (OntologyAnnotation("OldAnnotation"))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateAnnotationOfTermCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Parameter (OntologyAnnotation("MyParameter")),
[|CompositeCell.createTerm (OntologyAnnotation("OldAnnotation"))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
match copy.GetCellAt(0,0) with
| CompositeCell.Term oa -> oa.Name <- Some "NewAnnotation"
| _ -> Expect.isTrue false "Cell not term?"
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.createTerm (OntologyAnnotation("OldAnnotation"))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateUnitCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Parameter (OntologyAnnotation("MyParameter")),
[|CompositeCell.createUnitized("OldValue",(OntologyAnnotation("OldAnnotation")))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
copy.SetCellAt(0,0,CompositeCell.createUnitized("NewValue",(OntologyAnnotation("NewAnnotation"))))
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.createUnitized("OldValue",(OntologyAnnotation("OldAnnotation")))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
testCase "UpdateAnnotationOfUnitCell" <| fun _ ->
let table = ArcTable.init("NewTable")
table.AddColumn(
CompositeHeader.Parameter (OntologyAnnotation("MyParameter")),
[|CompositeCell.createUnitized("OldValue",(OntologyAnnotation("OldAnnotation")))|]
)
let copy = table.Copy()
Expect.equal copy table "Should be equal before change"
match copy.GetCellAt(0,0) with
| CompositeCell.Unitized (v,oa) -> oa.Name <- Some "NewAnnotation"
| _ -> Expect.isTrue false "Cell not unit?"
Expect.equal (table.GetCellAt(0,0)) (CompositeCell.createUnitized("OldValue",(OntologyAnnotation("OldAnnotation")))) "Cell of old table should stay as is"
Expect.notEqual copy table "Should not be equal after change"
]

let private tests_fillMissing = testList "fillMissing" [
testCase "OntologyAnnotationCopied" <| fun _ ->
Expand Down Expand Up @@ -2574,7 +2699,7 @@ let main =
tests_UpdateCellsBy
tests_UpdateColumn
tests_AddColumn_Mutable
tests_addColumn_Copy
tests_addColumn
tests_AddColumns
tests_AddColumnFill
tests_RemoveColumn
Expand All @@ -2591,5 +2716,6 @@ let main =
tests_IterColumns
tests_GetHashCode
tests_equality
tests_copy
tests_fillMissing
]
34 changes: 33 additions & 1 deletion tests/Core/Template.Tests.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Template.Tests
module Template.Tests

open Thoth.Json.Core

Expand Down Expand Up @@ -182,8 +182,40 @@ let private tests_filters = testList "filters" [
]
]

let private tests_copy = testList "Copy" [
testCase "DefaultEquality"<| fun _ ->
let template = create_TestTemplate()
let copy = template.Copy()
Expect.equal template copy "Templates should be equal"
testCase "StructuralEquality" <| fun _ ->
let template = create_TestTemplate()
let copy = template.Copy()
let equals = template.StructurallyEquals(copy)
Expect.isTrue equals "Structural equality should be true"
testCase "ReferenceEquality" <| fun _ ->
let template = create_TestTemplate()
let copy = template.Copy()
let equals = template.ReferenceEquals(copy)
Expect.isFalse equals "Reference equality should be false"
testCase "UpdatePerson" <| fun _ ->
let template = create_TestTemplate()
let copy = template.Copy()
Expect.equal template copy "Templates should be equal before change"
copy.Authors.[0].FirstName <- Some "Jane"
Expect.equal template.Authors.[0].FirstName (Some "John") "Name should not have been updated"
Expect.notEqual copy template "Templates should not be equal after change"
testCase "AddTableColumn" <| fun _ ->
let template = create_TestTemplate()
let copy = template.Copy()
Expect.equal template copy "Templates should be equal before change"
copy.Table.AddColumn(CompositeHeader.Parameter (OntologyAnnotation("VeryImportant")))
Expect.notEqual copy template "Templates should not be equal after change"
]


let main = testList "Templates" [
tests_equality
tests_HashCode
tests_filters
tests_copy
]

0 comments on commit 291198e

Please sign in to comment.