From a567a3da167a9e0eb81852dc019e3aaecc39dacb Mon Sep 17 00:00:00 2001 From: omaus Date: Tue, 22 Aug 2023 23:11:12 +0200 Subject: [PATCH] Fix unexpected hash mismatch --- build.cmd | 1 - playground.fsx | 41 +++++++++++++++++++++++-- src/ControlledVocabulary/CvContainer.fs | 9 +++++- src/ControlledVocabulary/CvObject.fs | 1 + src/ControlledVocabulary/CvParam.fs | 9 +++++- src/ControlledVocabulary/UserParam.fs | 7 ++++- 6 files changed, 61 insertions(+), 7 deletions(-) diff --git a/build.cmd b/build.cmd index 33614ea..76e30f3 100644 --- a/build.cmd +++ b/build.cmd @@ -1,4 +1,3 @@ @echo off -cls dotnet run --project ./build/Build.fsproj %* \ No newline at end of file diff --git a/playground.fsx b/playground.fsx index fbd45dc..aa85dbf 100644 --- a/playground.fsx +++ b/playground.fsx @@ -29,17 +29,52 @@ open System.Collections.Generic //#r @"C:\Repos\nfdi4plants\ArcGraphModel\src\ArcGraphModel\bin\Debug\netstandard2.0\ArcGraphModel.dll" //#r @"C:\Repos\nfdi4plants\ArcGraphModel\src\ArcGraphModel.IO\bin\Debug\netstandard2.0\ArcGraphModel.IO.dll" //#r @"C:/Users/olive/.nuget/packages/fsharpaux/1.1.0/lib/net5.0/FSharpAux.dll" -#r "src/ArcGraphModel/bin/Release/netstandard2.0/ArcGraphModel.dll" -#r "src/ControlledVocabulary/bin/Release/netstandard2.0/ControlledVocabulary.dll" +//#r "src/ArcGraphModel/bin/Release/netstandard2.0/ArcGraphModel.dll" +//#r "src/ControlledVocabulary/bin/Release/netstandard2.0/ControlledVocabulary.dll" +#I "src/ControlledVocabulary/bin/Debug/netstandard2.0" +#I "src/ControlledVocabulary/bin/Release/netstandard2.0" +#r "ControlledVocabulary.dll" +#I "src/ARCTokenization/bin/Debug/netstandard2.0" +#I "src/ARCTokenization/bin/Release/netstandard2.0" +#r "ARCTokenization.dll" open FsSpreadsheet open FsSpreadsheet.ExcelIO open FsOboParser //open FsSpreadsheet.DSL open ControlledVocabulary -open ControlledVocabulary.ParamBase +open type ControlledVocabulary.ParamBase open ARCTokenization +let testAccession1 = "TO:00000001" +let testName1 = "Test" +let testRef1 = "TO" + +let testTerm1 = CvTerm.create(accession = testAccession1, name = testName1, ref = testRef1) + +let testAccession2 = "TO:00000002" +let testName2 = "5" +let testRef2 = "TO" + +let testTerm2 = CvTerm.create(accession = testAccession2, name = testName2, ref = testRef2) + +let ``CvParam with ParamValue.Value`` = CvParam(testTerm1, ParamValue.Value 5) +let ``CvParam with ParamValue.CvValue`` = CvParam(testTerm1, ParamValue.CvValue testTerm2) +let ``CvParam with ParamValue.WithCvUnitAccession`` = CvParam(testTerm2, ParamValue.WithCvUnitAccession (5, testTerm1)) + +let testCvParams = + [ + ``CvParam with ParamValue.Value`` + ``CvParam with ParamValue.CvValue`` + ``CvParam with ParamValue.WithCvUnitAccession`` + ] +let testCvp1 = CvParam("test", "test", "test", ParamValue.Value "test", Dictionary() |> fun d -> d.Add("test", testCvParams.Head); d) +let testCvp2 = CvParam("test", "test", "test", ParamValue.Value "test", Dictionary() |> fun d -> d.Add("test", testCvParams.Head); d) +let actual = testCvp1 = testCvp2 +testCvp1.GetHashCode() +testCvp2.GetHashCode() + + let expectedTermValuesSimple = [ diff --git a/src/ControlledVocabulary/CvContainer.fs b/src/ControlledVocabulary/CvContainer.fs index e5fb3d7..f90eb6e 100644 --- a/src/ControlledVocabulary/CvContainer.fs +++ b/src/ControlledVocabulary/CvContainer.fs @@ -44,12 +44,19 @@ type CvContainer ( CvContainer(term, dict) new (term : CvTerm) = CvContainer (term, Seq.empty) + /// Serves as the default hash function. override this.GetHashCode() = hash (cvAccession, cvName, cvRef, attributes, properties) + /// Determines whether the specified object is equals to the current object. override this.Equals(o) = match o with - | :? CvContainer as cvc -> cvc.GetHashCode() = this.GetHashCode() + | :? CvContainer as cvc -> + (cvc :> ICvBase).Accession = (this :> ICvBase).Accession && + (cvc :> ICvBase).Name = (this :> ICvBase).Name && + (cvc :> ICvBase).RefUri = (this :> ICvBase).RefUri && + cvc.Attributes = this.Attributes && + cvc.Properties = this.Properties | :? ICvBase as cvb -> CvBase.equals cvb this | _ -> false diff --git a/src/ControlledVocabulary/CvObject.fs b/src/ControlledVocabulary/CvObject.fs index a8327f3..6b1151b 100644 --- a/src/ControlledVocabulary/CvObject.fs +++ b/src/ControlledVocabulary/CvObject.fs @@ -22,6 +22,7 @@ type CvObject<'T>(cvAccession : string, cvName : string, cvRef : string, object | :? ICvBase as cvb -> CvBase.equals cvb this | _ -> false + /// Serves as the default hash function. override this.GetHashCode() = hash (cvAccession, cvName, cvRef, attributes) diff --git a/src/ControlledVocabulary/CvParam.fs b/src/ControlledVocabulary/CvParam.fs index 77efa9d..c0a116e 100644 --- a/src/ControlledVocabulary/CvParam.fs +++ b/src/ControlledVocabulary/CvParam.fs @@ -45,13 +45,20 @@ type CvParam(cvAccession : string, cvName : string, cvRef : string, paramValue : new (cvTerm,v : IConvertible) = CvParam (cvTerm,ParamValue.Value v) + /// Serves as the default hash function. override this.GetHashCode() = hash (cvAccession, cvName, cvRef, paramValue, attributes) + /// Determines whether the specified object is equals to the current object. override this.Equals(o) = match o with | :? CvTerm as cvt -> Param.equalsTerm cvt this - | :? CvParam as cvp -> cvp.GetHashCode() = this.GetHashCode() + | :? CvParam as cvp -> + cvp.Name = this.Name && + cvp.Accession = this.Accession && + cvp.RefUri = this.RefUri && + cvp.Value = this.Value && + cvp.Attributes = this.Attributes // careful bc of Dictionary! Comment out if necessary! | :? IParam as p -> p.Name = this.Name && p.Accession = this.Accession && diff --git a/src/ControlledVocabulary/UserParam.fs b/src/ControlledVocabulary/UserParam.fs index 465f6e6..ce78c83 100644 --- a/src/ControlledVocabulary/UserParam.fs +++ b/src/ControlledVocabulary/UserParam.fs @@ -31,13 +31,18 @@ type UserParam(name : string, paramValue : ParamValue, attributes : IDictionary< new (name,pv) = UserParam (name,pv,Seq.empty) + /// Serves as the default hash function. override this.GetHashCode() = hash (name, paramValue, attributes) + /// Determines whether the specified object is equals to the current object. override this.Equals(o) = match o with | :? CvTerm as cvt -> Param.equalsTerm cvt this - | :? UserParam as up -> this.GetHashCode() = up.GetHashCode() + | :? UserParam as up -> + up.Name = this.Name && + up.Value = this.Value && + up.Attributes = this.Attributes | :? IParam as p -> p.Name = this.Name && p.Value = this.Value