Question
· Mar 7

How to compare two Registered Object

I would like to compare two Registered Object and list the properties that differ.

For now, I achieve this :
 

ClassMethod AssertObjectEquals(object As %RegisteredObject, objectToCompare As %RegisteredObject, Output msg As %String) As %Status
{
        Set returnValue = 1
        // check if same class
        Set className = $CLASSNAME(object)
        If (className '= $CLASSNAME(objectToCompare)) {
                Set returnValue = 0
                Set difference = "not same class"
        }

        If (returnValue) {
                // Get the definition to browse properties
                Set classDef = ##class(%Library.ClassDefinition).%OpenId(className)
                Set propertiesDef = classDef.Properties
                // Check the value for each property
                Set difference = ""
                For i = 1:1:propertiesDef.Count() {
                        Set propertyName = propertiesDef.GetAt(i).Name
                        Set propertyValue = $PROPERTY(object,propertyName)
                        // if different, supply the variable difference with the name of property + value
                        If ((propertyValue '= "") && (propertyValue '= $PROPERTY(objectToCompare,propertyName)))
                        {
                                Set difference = difference _ "; " _ propertyName _ " = " _ propertyValue
                        }
                }
        }
        if difference = ""
                {Set msg = "equal"}
        else {
                Set msg = difference
        }
        Return $$$OK
}

But it does not take into account complex properties as list, array or object.

Has somebody an idea to complete the ClassMethod or an other totally  different solution?

Thanks in advance !

Product version: Ensemble 2018.1
$ZV: Cache for Windows (x86-64) 2018.1.4 (Build 505_1U) Thu May 28 2020 10:01:40 EDT
Discussion (6)4
Log in or sign up to continue

Hello Corentin,

I took your code as base and improved it a bit to compare complex object: 

ClassMethod CompareObjects(expectedObject As %RegisteredObject, actualObject As %RegisteredObject) As %Status

{

        Set status= $$$OK

        Set returnValue = 1

       

        Try{

        // check if same class                                            

        Set className = $CLASSNAME(expectedObject)

        If (className '= $CLASSNAME(actualObject)) {

                Set returnValue = 0

                Set ^||differences(expectedObject,actualObject) = "not same class"

        }

        If (returnValue) {

            // Get the definition to browse properties

            Set classDef = ##class(%Library.ClassDefinition).%OpenId(className)

            Set propertiesDef = classDef.Properties

            // Check the value for each property

           

            For i = 1:1:propertiesDef.Count() {

                Set propertyName = propertiesDef.GetAt(i).Name

                Set propertyValueExpected = $PROPERTY(expectedObject,propertyName)

                Set propertyValueActual=$PROPERTY(actualObject,propertyName)

               

                // if different, supply the variable difference with the name of property + value



                If $ISOBJECT(propertyValueExpected){

                    If propertyValueExpected.%Extends("%Collection.Super"){

                        For ii=1:1:propertyValueExpected.Count(){

                            Set tSC= ..CompareObjects(propertyValueExpected.GetAt(ii),propertyValueActual.GetAt(ii))

                        }

                    }

                    Else{

                        Set tSC= ..CompareObjects(propertyValueExpected,propertyValueActual)

                    }

                }

                Else{

                    If ((propertyValueExpected '= "") && (propertyValueExpected '= propertyValueActual))

                    {                                                                                                              

                        Set ^||differences(expectedObject,propertyName)=propertyValueExpected _ " != " _ propertyValueActual

                    }

                }

                   

            }

       

        }

        }Catch e{

            Set status=e.AsStatus()

        }

         

        Quit status

}



ClassMethod AssertObjectEquals(expectedObject As %RegisteredObject, actualObject As %RegisteredObject, Output msg) As %Status

{

    Set status=$$$OK

    Set status=..CompareObjects(expectedObject,actualObject)


    If $DATA(^||differences){

        Set key=$ORDER(^||differences(""))

        Set key2=$ORDER(^||differences(key,""))

        Set msg=""

        While key'=""{

            While key2'=""{

                Set msg = msg_"; "_key2_": "_^||differences(key,key2)

                Set key2=$ORDER(^||differences(key,key2))

            }

            Set key=$ORDER(^||differences(key))

            Set:(key'="") key2=$ORDER(^||differences(key,""))

        }

        If $LENGTH(msg){

            Quit $$$ERROR(1,"Objects not equal")

        }

    }

    Quit status

}

 Please give me your opinion if there's anything to improve