From 54234127e96589c1924beabd307c7ea10c85f7d0 Mon Sep 17 00:00:00 2001
From: Vivien Nicolas <vnicolas@apple.com>
Date: Thu, 14 Sep 2023 20:26:13 +0200
Subject: [PATCH] [MatterYamlTests] Properly translate descriptionString to
 description for YAML tests running with darwin-framework-tool (#29251)

[MatterYamlTests] Convert fabricIndex field properly when darwin-framework-tool is used and convert names that starts with an acronym properly as well
---
 .../matter_chip_tool_adapter/decoder.py       | 64 ++++++++++++-------
 1 file changed, 41 insertions(+), 23 deletions(-)

diff --git a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py
index dc721b24268447..a7dd32b7d43a85 100644
--- a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py
+++ b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py
@@ -14,6 +14,7 @@
 
 import base64
 import json
+import re
 
 # These constants represent the vocabulary used for the incoming JSON.
 _CLUSTER_ID = 'clusterId'
@@ -43,6 +44,7 @@
 # a field is used for a fabric scoped struct.
 _FABRIC_INDEX_FIELD_CODE = '254'
 _FABRIC_INDEX_FIELD_NAME = 'FabricIndex'
+_FABRIC_INDEX_FIELD_NAME_DARWIN = 'fabricIndex'
 _FABRIC_INDEX_FIELD_TYPE = 'int8u'
 
 
@@ -289,44 +291,60 @@ def run(self, specs, value, cluster_name: str, typename: str, array: bool):
                 field_name = field.name
                 field_type = field.data_type.name
                 field_array = field.is_list
-                # chip-tool returns the field code as an integer but the test suite expects
-                # a field name.
-                # To not confuse the test suite, the field code is replaced by its field name
-                # equivalent and then removed.
+
+                provided_field_name = field_name
+
                 if str(field_code) in value:
-                    value[field_name] = self.run(
-                        specs,
-                        value[str(field_code)],
-                        cluster_name,
-                        field_type,
-                        field_array
+                    # chip-tool returns the field code as an integer but the test suite expects
+                    # a field name.
+                    # To not confuse the test suite, the field code is replaced by its field name
+                    # equivalent and then removed.
+                    provided_field_name = str(field_code)
+                else:
+                    # darwin-framework-tool returns the field name but with a different casing than
+                    # what the test suite expects.
+                    # To not confuse the test suite, the field name is replaced by its field name
+                    # equivalent from the spec and then removed.
+
+                    if field_name == 'Description' and 'descriptionString' in value:
+                        # "Description" is returned as "descriptionString" since 'description' is a reserved keyword
+                        # and can not be exposed in an objc struct.
+                        provided_field_name = 'descriptionString'
+
+                    # If field_name starts with a sequence of capital letters lowercase all but the last one.
+                    provided_field_name = re.sub(
+                        '^([A-Z]+)([A-Z])',
+                        lambda m: m.group(1).lower() + m.group(2),
+                        provided_field_name
                     )
-                    del value[str(field_code)]
-
-                # darwin-framework-tool returns the field name but with a different casing than what
-                # the test suite expects.
-                # To not confuse the test suite, the field name is replaced by its field name
-                # equivalent from the spec and then removed.
-                wrong_casing_field_name = field_name[0].lower(
-                ) + field_name[1:]
-                if field_name not in value and field_name[0].upper() == field_name[0] and wrong_casing_field_name in value:
+
+                    # All field names in darwin-framework-tool start with a lowercase letter.
+                    provided_field_name = provided_field_name[0].lower(
+                    ) + provided_field_name[1:]
+
+                if provided_field_name in value:
                     value[field_name] = self.run(
                         specs,
-                        value[wrong_casing_field_name],
+                        value[provided_field_name],
                         cluster_name,
                         field_type,
                         field_array
                     )
-                    del value[wrong_casing_field_name]
+                    del value[provided_field_name]
 
             if specs.is_fabric_scoped(struct):
+                if _FABRIC_INDEX_FIELD_CODE in value:
+                    key_name = _FABRIC_INDEX_FIELD_CODE
+                elif _FABRIC_INDEX_FIELD_NAME_DARWIN in value:
+                    key_name = _FABRIC_INDEX_FIELD_NAME_DARWIN
+
                 value[_FABRIC_INDEX_FIELD_NAME] = self.run(
                     specs,
-                    value[_FABRIC_INDEX_FIELD_CODE],
+                    value[key_name],
                     cluster_name,
                     _FABRIC_INDEX_FIELD_TYPE,
                     False)
-                del value[_FABRIC_INDEX_FIELD_CODE]
+                del value[key_name]
 
         elif isinstance(value, list) and array:
             value = [self.run(specs, v, cluster_name, typename, False)