# Path: jirafs/jirafieldmanager.py
# class JiraFieldManager(dict):
#     FIELD_MATCHER = re.compile(
#         "^%s$"
#         % (constants.TICKET_FILE_FIELD_TEMPLATE.replace("{field_name}", r"([\w_]+)"))
#     )
# 
#     def __init__(self, data=None, names=None):
#         if names is None:
#             self._data, self._names = self.get_fields_from_string(data)
#         else:
#             self._data = data
#             self._names = names
#         super(JiraFieldManager, self).__init__(self._data)
# 
#     def __sub__(self, other):
#         differing = {}
#         for k in other.keys():
#             v = other.get_transformed(k, None)
#             if (self.get_transformed(k, None) or v) and self.get_transformed(
#                 k, None
#             ) != v:
#                 tx = self.get_transformed(k, None)
#                 differing[k] = (
#                     v,
#                     tx,
#                     self.get_transformed(k, None),
#                 )
# 
#         return differing
# 
#     def get_human_name_for_field(self, field):
#         try:
#             return self._names[field]
#         except KeyError:
#             return field
# 
#     def items_transformed(self):
#         for k, v in self.items():
#             if k in self.get_requested_per_ticket_fields():
#                 result = self.folder.process_macros(
#                     v, path=self.get_generated_file_path()
#                 )
#                 yield k, result
#             else:
#                 yield k, v
# 
#     def get_transformed(self, field_name, default=None):
#         try:
#             if field_name not in self.get_requested_per_ticket_fields():
#                 return self[field_name]
# 
#             return self.folder.process_macros(
#                 self[field_name], path=self.get_generated_file_path()
#             )
#         except KeyError:
#             return default
# 
#     @classmethod
#     def create(cls, folder, revision=None, path=None):
#         if revision and path:
#             raise TypeError("You may specify a git revision or a local path; not both.")
# 
#         if revision:
#             return GitRevisionJiraFieldManager(folder, revision)
#         else:
#             return WorkingCopyJiraFieldManager(folder, path)
# 
#     def get_requested_per_ticket_fields(self):
#         return constants.FILE_FIELDS
# 
#     def get_used_per_ticket_fields(self):
#         raise NotImplementedError()
# 
#     def get_field_data_files(self):
#         all_files = [
#             constants.TICKET_DETAILS,
#         ]
# 
#         try:
#             for field in self.get_used_per_ticket_fields():
#                 all_files.append(
#                     constants.TICKET_FILE_FIELD_TEMPLATE.format(
#                         field_name=field,
#                     )
#                 )
#         except NotImplementedError:
#             pass
# 
#         for field in self.get_requested_per_ticket_fields():
#             all_files.append(
#                 constants.TICKET_FILE_FIELD_TEMPLATE.format(
#                     field_name=field,
#                 )
#             )
# 
#         return all_files
# 
#     def set_data_value(self, data, field_name, raw_value):
#         raw_value = raw_value.strip()
#         try:
#             value = json.loads(raw_value)
#         except (TypeError, ValueError):
#             value = raw_value
#         data[field_name] = value
# 
#     def get_fields_from_string(self, string):
#         """Gets field data from an incoming string.
# 
#         Parses through the string using the following RST-derived
#         pattern::
# 
#             0 | * Field
#             1 |     VALUE
#             2 |     MORE VALUE
# 
#         """
#         data = {}
#         field_name = ""
#         human_names = {}
#         value = ""
#         if not string:
#             return data, human_names
#         lines = string.split("\n")
#         for idx, line in enumerate(lines):
#             if line.startswith("*"):
#                 if value:  # If so, we just need to store previous loop data
#                     self.set_data_value(data, field_name, value)
#                     value = ""
#                 raw_field_name = re.match(r"^\* (.*\(.*?\)):$", line).group(1)
#                 if "(" in raw_field_name:
#                     # This field name's real name doesn't match the field ID
#                     match = re.match(r"(.*) \(([^)]+)\)", raw_field_name)
#                     field_name = match.group(2)
#                     human_names[field_name] = match.group(1)
#                 else:
#                     field_name = raw_field_name.replace(" ", "_")
#             elif field_name:
#                 value = value + "\n" + line.strip()
#         if value:
#             self.set_data_value(data, field_name, value)
# 
#         return data, human_names


from textwrap import dedent
from unittest import TestCase
from jirafs.jirafieldmanager import JiraFieldManager
            * Dictionary Field (dictionary_field):
                {
                    "name": "Adam Coddington"
                }
            * Integer Field (integer_field):
                10
            * String Field (string_field):
                Hello
            * List Field (list_field):
                [
                    "Alphabet",
                    {
                        "One": "Two"
                    }
                ]
        """
        )

        expected_result = {
            "dictionary_field": {"name": "Adam Coddington"},
            "integer_field": 10,
            "string_field": "Hello",
            "list_field": [
                "Alphabet",
                {
                    "One": "Two",
                },
            ],
        }


# Path: jirafs/jirafieldmanager.py
# class JiraFieldManager(dict):
#     FIELD_MATCHER = re.compile(
#         "^%s$"
#         % (constants.TICKET_FILE_FIELD_TEMPLATE.replace("{field_name}", r"([\w_]+)"))
#     )
# 
#     def __init__(self, data=None, names=None):
#         if names is None:
#             self._data, self._names = self.get_fields_from_string(data)
#         else:
#             self._data = data
#             self._names = names
#         super(JiraFieldManager, self).__init__(self._data)
# 
#     def __sub__(self, other):
#         differing = {}
#         for k in other.keys():
#             v = other.get_transformed(k, None)
#             if (self.get_transformed(k, None) or v) and self.get_transformed(
#                 k, None
#             ) != v:
#                 tx = self.get_transformed(k, None)
#                 differing[k] = (
#                     v,
#                     tx,
#                     self.get_transformed(k, None),
#                 )
# 
#         return differing
# 
#     def get_human_name_for_field(self, field):
#         try:
#             return self._names[field]
#         except KeyError:
#             return field
# 
#     def items_transformed(self):
#         for k, v in self.items():
#             if k in self.get_requested_per_ticket_fields():
#                 result = self.folder.process_macros(
#                     v, path=self.get_generated_file_path()
#                 )
#                 yield k, result
#             else:
#                 yield k, v
# 
#     def get_transformed(self, field_name, default=None):
#         try:
#             if field_name not in self.get_requested_per_ticket_fields():
#                 return self[field_name]
# 
#             return self.folder.process_macros(
#                 self[field_name], path=self.get_generated_file_path()
#             )
#         except KeyError:
#             return default
# 
#     @classmethod
#     def create(cls, folder, revision=None, path=None):
#         if revision and path:
#             raise TypeError("You may specify a git revision or a local path; not both.")
# 
#         if revision:
#             return GitRevisionJiraFieldManager(folder, revision)
#         else:
#             return WorkingCopyJiraFieldManager(folder, path)
# 
#     def get_requested_per_ticket_fields(self):
#         return constants.FILE_FIELDS
# 
#     def get_used_per_ticket_fields(self):
#         raise NotImplementedError()
# 
#     def get_field_data_files(self):
#         all_files = [
#             constants.TICKET_DETAILS,
#         ]
# 
#         try:
#             for field in self.get_used_per_ticket_fields():
#                 all_files.append(
#                     constants.TICKET_FILE_FIELD_TEMPLATE.format(
#                         field_name=field,
#                     )
#                 )
#         except NotImplementedError:
#             pass
# 
#         for field in self.get_requested_per_ticket_fields():
#             all_files.append(
#                 constants.TICKET_FILE_FIELD_TEMPLATE.format(
#                     field_name=field,
#                 )
#             )
# 
#         return all_files
# 
#     def set_data_value(self, data, field_name, raw_value):
#         raw_value = raw_value.strip()
#         try:
#             value = json.loads(raw_value)
#         except (TypeError, ValueError):
#             value = raw_value
#         data[field_name] = value
# 
#     def get_fields_from_string(self, string):
#         """Gets field data from an incoming string.
# 
#         Parses through the string using the following RST-derived
#         pattern::
# 
#             0 | * Field
#             1 |     VALUE
#             2 |     MORE VALUE
# 
#         """
#         data = {}
#         field_name = ""
#         human_names = {}
#         value = ""
#         if not string:
#             return data, human_names
#         lines = string.split("\n")
#         for idx, line in enumerate(lines):
#             if line.startswith("*"):
#                 if value:  # If so, we just need to store previous loop data
#                     self.set_data_value(data, field_name, value)
#                     value = ""
#                 raw_field_name = re.match(r"^\* (.*\(.*?\)):$", line).group(1)
#                 if "(" in raw_field_name:
#                     # This field name's real name doesn't match the field ID
#                     match = re.match(r"(.*) \(([^)]+)\)", raw_field_name)
#                     field_name = match.group(2)
#                     human_names[field_name] = match.group(1)
#                 else:
#                     field_name = raw_field_name.replace(" ", "_")
#             elif field_name:
#                 value = value + "\n" + line.strip()
#         if value:
#             self.set_data_value(data, field_name, value)
# 
#         return data, human_names


# Path: tests/test_jirafieldmanager.py
from textwrap import dedent
from unittest import TestCase
from jirafs.jirafieldmanager import JiraFieldManager

            * Dictionary Field (dictionary_field):
                {
                    "name": "Adam Coddington"
                }
            * Integer Field (integer_field):
                10
            * String Field (string_field):
                Hello
            * List Field (list_field):
                [
                    "Alphabet",
                    {
                        "One": "Two"
                    }
                ]
        """
        )

        expected_result = {
            "dictionary_field": {"name": "Adam Coddington"},
            "integer_field": 10,
            "string_field": "Hello",
            "list_field": [
                "Alphabet",
                {
                    "One": "Two",
                },
            ],
        }


        actual_result = JiraFieldManager(encoded_values)