Skip to content
Merged
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
2 changes: 2 additions & 0 deletions src/DynamicObj/DynamicObj.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
| Some pi -> Some pi
| None -> this.TryGetDynamicPropertyHelper propertyName

/// <summary>

Check warning on line 78 in src/DynamicObj/DynamicObj.fs

View workflow job for this annotation

GitHub Actions / test (windows-latest)

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

Check warning on line 78 in src/DynamicObj/DynamicObj.fs

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

This XML comment is incomplete: no documentation for parameter 'propertyName'
/// Returns Some(boxed property value) if a dynamic (or static) property with the given name exists, otherwise None.
/// </summary>
/// <param name="name">the name of the property to get</param>
Expand Down Expand Up @@ -421,6 +421,8 @@
HashCodes.mergeHashes (hash c.Key) (HashUtils.deepHash c.Value)
]
|> fun l -> if l.IsEmpty then 0 else l |> List.reduce HashCodes.mergeHashes
| ReflectionUtils.SomeObj s ->
HashUtils.deepHash s
#endif
| :? System.Collections.IEnumerable as e ->
let en = e.GetEnumerator()
Expand Down
21 changes: 21 additions & 0 deletions src/DynamicObj/ReflectionUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,24 @@ module ReflectionUtils =
property.RemoveValue(o)
true
| _ -> false

#if !FABLE_COMPILER
/// matches if the matched object can be parsed to Some 'a and returns it.
let internal (|SomeObj|_|) =
/// create generalized option type
let ty = typedefof<option<_>>
fun (a:obj) ->
/// Check for nulls otherwise 'a.GetType()' would fail
if isNull a
then
None
else
let aty = a.GetType()
/// Get option'.Value
let v = aty.GetProperty("Value")
if aty.IsGenericType && aty.GetGenericTypeDefinition() = ty then
/// return value if existing
Some(v.GetValue(a, [| |]))
else
None
#endif
62 changes: 62 additions & 0 deletions tests/DynamicObject.Tests/HashUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ let resizeArray1 = ResizeArray [int1;int2;int3;int4]
let resizeArray1' = ResizeArray [int1;int2;int3;int4]
let resizeArray2 = ResizeArray [int1;int4;int3;int2]

let option1 = Some int1
let option2 = Some int2
let option1' = Some int1
let optionNone : obj option = None

let optionResizeArray1 = Some resizeArray1
let optionResizeArray1' = Some resizeArray1'
let optionResizeArray2 = Some resizeArray2
let optionResizeArrayNone : ResizeArray<obj> option = None

let dynamicObjectWithInt1 =

Expand Down Expand Up @@ -122,6 +131,25 @@ let dynamicObjectWithDynamicObject2 =
d.SetProperty("b", dynamicObjectWithDict1)
d

let dynamicObjectWithOption1 =
let d = DynamicObj()
d.SetProperty("a", option1)
d

let dynamicObjectWithOption1' =
let d = DynamicObj()
d.SetProperty("a", option1')
d

let dynamicObjectWithOption2 =
let d = DynamicObj()
d.SetProperty("a", option2)
d

let dynamicObjectWithOptionNone =
let d = DynamicObj()
d.SetProperty("a", optionNone)
d

let tests_Dictionary =
testList "Dictionary" [
Expand Down Expand Up @@ -210,6 +238,29 @@ let tests_ResizeArray =
]
]

let tests_Option =
testList "Option" [
testList "Int" [
testCase "Some vs Some" <| fun _ ->
Expect.equal (HashUtils.deepHash option1) (HashUtils.deepHash option1') "Structurally equal Some should return consistent Hash"
testCase "Some vs Some Different" <| fun _ ->
Expect.notEqual (HashUtils.deepHash option1) (HashUtils.deepHash option2) "Different Some should return different Hash"
testCase "Some vs None" <| fun _ ->
Expect.notEqual (HashUtils.deepHash option1) (HashUtils.deepHash optionNone) "Some vs None should return different Hash"
testCase "None vs None" <| fun _ ->
Expect.equal (HashUtils.deepHash optionNone) (HashUtils.deepHash optionNone) "None vs None should return consistent Hash"
]
testList "ResizeArray" [
testCase "Some vs Some" <| fun _ ->
Expect.equal (HashUtils.deepHash optionResizeArray1) (HashUtils.deepHash optionResizeArray1') "Structurally equal Some ResizeArray should return consistent Hash"
testCase "Some vs Some Different" <| fun _ ->
Expect.notEqual (HashUtils.deepHash optionResizeArray1) (HashUtils.deepHash optionResizeArray2) "Different Some ResizeArray should return different Hash"
testCase "Some vs None" <| fun _ ->
Expect.notEqual (HashUtils.deepHash optionResizeArray1) (HashUtils.deepHash optionResizeArrayNone) "Some ResizeArray vs None should return different Hash"
testCase "None vs None" <| fun _ ->
Expect.equal (HashUtils.deepHash optionResizeArrayNone) (HashUtils.deepHash optionResizeArrayNone) "None ResizeArray vs None ResizeArray should return consistent Hash"
]
]

let tests_DynamicObject =
testList "DynamicObj" [
Expand Down Expand Up @@ -252,6 +303,16 @@ let tests_DynamicObject =
Expect.notEqual (HashUtils.deepHash (Some dynamicObjectWithInt1)) (HashUtils.deepHash None) "Different DynamicObject should return different Hash"

]
testList "Option" [
testCase "Some vs Some" <| fun _ ->
Expect.equal (HashUtils.deepHash dynamicObjectWithOption1) (HashUtils.deepHash dynamicObjectWithOption1') "Structurally equal Some should return consistent Hash"
testCase "Some vs Some Different" <| fun _ ->
Expect.notEqual (HashUtils.deepHash dynamicObjectWithOption1) (HashUtils.deepHash dynamicObjectWithOption2) "Different Some should return different Hash"
testCase "Some vs None" <| fun _ ->
Expect.notEqual (HashUtils.deepHash dynamicObjectWithOption1) (HashUtils.deepHash dynamicObjectWithOptionNone) "Some vs None should return different Hash"
testCase "None vs None" <| fun _ ->
Expect.equal (HashUtils.deepHash dynamicObjectWithOptionNone) (HashUtils.deepHash dynamicObjectWithOptionNone) "None vs None should return consistent Hash"
]
testList "Mixed" [
testCase "Int vs Dict" <| fun _ ->
Expect.notEqual (HashUtils.deepHash dynamicObjectWithInt1) (HashUtils.deepHash dynamicObjectWithDict1) "Int vs Dict with same values should return different Hash"
Expand All @@ -278,6 +339,7 @@ let main = testList "DeepHash" [
tests_Array
tests_Seq
tests_ResizeArray
tests_Option
tests_DynamicObject
tests_Mixed
]
Loading