generate tests for this code:
import json
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Dict
from typing import List, Union

import pyperclip
from aenum import MultiValueEnum

from code\_keeper import cast\_enum
class GardenArea(MultiValueEnum):
 main = 1, 'main'
 secondary = 2, 'secondary'
 inbox = 3, 'inbox'
@dataclass
class CodeFragment:
 code: str
 tags: List[str]
 area: GardenArea

 @property
 def name(self):
 return '.'.join(self.tags)
 # name: str
 # categories: List[str]
 # id: str = None
 #
 # def \_\_post\_init\_\_(self):
 # if self.id is None:
 # self.id = str(uuid.uuid4())
 # # todo: \_record\_event - creation
DEFAULT\_GARDEN\_ROOT = os.path.expanduser('~/.code\_garden')
class CodeGarden:
 def \_\_init\_\_(self, path=None):
 if path is None:
 path = self.\_find\_garden()
 self.path = Path(path).expanduser()
 # create if not exists
 self.path.mkdir(parents=True, exist\_ok=True)

 @staticmethod
 def \_find\_garden():
 return os.getenv('CODE\_GARDEN\_ROOT', DEFAULT\_GARDEN\_ROOT)

 @staticmethod
 def \_cast\_area(area):
 return cast\_enum(area, GardenArea)

 def find(self,
 keys, area: Union[str, GardenArea] = None,
 keys\_and: bool = True
 ) -> Dict[str, CodeFragment]:
 if isinstance(area, str):
 area = self.\_cast\_area(area)
 areas = [area] if area is not None else GardenArea
 result = {}
 for area in areas:
 for path in self.\_find\_paths(keys, area, keys\_and):
 code = path.read\_text()
 tags = path.stem.split('.')
 code\_fragment = CodeFragment(code, tags, area)
 result[code\_fragment.name] = code\_fragment
 return result

 def \_find\_paths(self, keys, area: GardenArea, keys\_and: bool = True):
 area\_path = self.path / area.value

 for path in area\_path.iterdir():
 # just take .py files
 if path.suffix == '.py' and path.is\_file():
 if keys\_and and all(key in path.stem for key in keys):
 yield path
 elif any(key in path.stem for key in keys):
 yield path

 def save(self, code, tags, area, metadata=None, force=False):
 # todo: check if code is already saved
 path = self.\_generate\_path(area, tags)
 if path.exists() and not force:
 raise ValueError(f'Code already exists at {path}')
 path.parent.mkdir(parents=True, exist\_ok=True)
 with path.open('w') as f:
 if metadata is not None:
 f.write('# metadata ')
 json.dump(metadata, f)
 f.write(code)

 def \_generate\_path(self, area, tags, ext='.py'):
 if not ext.startswith('.'):
 ext = '.' + ext
 return self.path / area.value / '.'.join(tags) + ext
class CodeKeeper:
 def \_\_init\_\_(self, code\_garden: CodeGarden = None):
 if code\_garden is None:
 code\_garden = CodeGarden() # finds path automatically
 elif isinstance(code\_garden, str):
 code\_garden = CodeGarden(code\_garden)
 self.code\_garden = code\_garden

 # todo: read to\_clipboard from config (env)
 def remind(self, keys: Union[str, List[str]] = None, area: Union[str,
 GardenArea] = None, keys\_and: bool = True, to\_clipboard=True) -> Dict[str,
 CodeFragment]:
 # step 1: parse the keys
 if keys is None:
 keys = ['remind']
 keys = self.\_parse\_keys(keys)

 # step 2: find the code
 code\_fragments = self.code\_garden.find(keys, area, keys\_and)

 # step 3: compose the formatted code
 res = ""
 for code\_fragment in sorted(code\_fragments.values(),
 key=lambda x: x.area.value):
 res += f"# {code\_fragment.name}"
 res += f"{code\_fragment.code}"
 res += f"\n\n"
 # todo: formatted code for jupyter

 # step 4: copy the code to the clipboard
 if to\_clipboard:
 pyperclip.copy(res)

 return res

 @staticmethod
 def \_parse\_keys(keys):
 if isinstance(keys, str):
 keys = keys.split('.')
 return keys

 find = remind

 def plant(self, code, tagline, area: Union[str, GardenArea] =
 GardenArea.inbox, force=False):
 # step 1: parse the tagline
 if '/' in tagline:
 area, tagline = tagline.rsplit('/', 1)
 tags = self.\_parse\_tagline(tagline)

 # step 2: save the code
 self.code\_garden.save(
 code, tags, area, force=force
 )

 def \_parse\_tagline(self, tagline):
 return tagline.split('.')

 add = plant

 def generate\_summary(self):
 summary = ""
 # genereate summary by tag (most used)
 summary += self.code\_garden.\_generate\_summary\_by\_tag()

 # todo: generate summary by usage (most visited / least visited)
 # todo: generate summary by creaetion date (most recent few)
 # todo: something else? How do I highlight the most important code?
 # random items just in case? :)
 return summary
 # todo: figure out intuitive name for this

 # todo: SECTIONS TO ADD
 # SECTION 1: HOUSEKEEPING - sorting inbox etc.
 # SECTION 2: add Categories, Generate with AI, use for summary
 # SECTION 3: add logging, use for summary
 # SECTION 4: Notion, sync on startup, sync on save

 # def housekeeping(self):
 # """Go over the garden and see about the plant names"""
 # # 1) start with main first, then inbox, then secondary
 # # 2) mark completed, completion time
 # # 3) revisit
 # # 4) revisit everything globally
 # # 5) keep a global tag registry - with counts and introduction date / event dates.
 # # 6) if there were many tag updates since the plant is finalised
 # # 7) periodically run housekeeping. Send the requests for input through telegram
MemoryKeeper = CodeKeeper
이 코드에 대한 테스트를 실행합니다:import jsonimport osfrom dataclasses import dataclasspathlib에서 Path입력에서 딕셔너리 임포트유형에서 목록, 유니온 임포트파이퍼클립 임포트열거형에서 MultiValueEnum 임포트코드\_키퍼에서 cast\_enum을 가져옵니다.클래스 GardenArea(MultiValueEnum): main = 1, 'main' secondary = 2, 'secondary' 받은 편지함 = 3, '받은 편지함'데이터클래스코드 조각 클래스: 코드: str 태그: List[str] area: GardenArea @property def name(self): 반환 '.'.join(self.tags) # 이름: str # 카테고리: List[str] # id: str = None # # def \_\_post\_init\_\_(self): # self.id가 None이면 # self.id = str(uuid.uuid4()) # # todo: \_RECORD\_EVENT - 생성DEFAULT\_GARDEN\_ROOT = os.path.expanduser('~/.code\_garden')코드가든 클래스: def \_\_init\_\_(self, path=None): 경로가 None이면 path = self.\_find\_garden() self.path = Path(path).expanduser() # 존재하지 않으면 생성 self.path.mkdir(parents=True, exist\_ok=True) 정적 메서드 def \_find\_garden(): return os.getenv('CODE\_GARDEN\_ROOT', DEFAULT\_GARDEN\_ROOT) 정적 메서드 def \_cast\_area(area): return cast\_enum(area, GardenArea) def find(self, keys, area: Union[str, GardenArea] = None, keys\_and: bool = True ) -> Dict[str, CodeFragment]: if isinstance(area, str): area = self.\_cast\_area(area) 영역 = [영역] 영역이 None이 아닌 경우 GardenArea 결과 = {} 영역의 영역에 대해 for path in self.\_find\_paths(keys, area, keys\_and): code = path.read\_text() tags = path.stem.split('.') code\_fragment = CodeFragment(코드, 태그, 영역) 결과[코드\_프래그먼트.이름] = 코드\_프래그먼트 결과 반환 def \_find\_paths(self, keys, area: GardenArea, keys\_and: bool = True): area\_path = self.path / area.value for path in area\_path.iterdir(): # .py 파일만 가져옵니다. 경로 접미사 == '.py' 및 경로가\_파일(): if keys\_and and all(경로의 줄기에 있는 키에 대해 경로의 키): 경로 반환 elif any(경로.줄기에 있는 키에 대해 키에 있는 키): 경로 반환 def save(self, code, tags, area, metadata=None, force=False): # 할일: 코드가 이미 저장되었는지 확인 path = self.\_generate\_path(영역, 태그) path.exists()가 아니고 force가 아닌 경우: ValueError(f'{path}에 코드가 이미 존재합니다') 발생 path.parent.mkdir(parents=True, exist\_ok=True) 경로.열기('w')를 f로 사용합니다: 메타데이터가 None이 아닌 경우: f.write('# 메타데이터 ') json.덤프(메타데이터, f) f.write(code) def \_generate\_path(self, area, tags, ext='.py'): if not ext.startswith('.'): ext = '.' + ext 반환 self.path / area.value / '.'.join(tags) + ext코드키퍼 클래스: def \_\_init\_\_(self, code\_garden: CodeGarden = None): code\_garden이 None이면 code\_garden = CodeGarden() # 자동으로 경로 찾기 elif isinstance(code\_garden, str): code\_garden = CodeGarden(code\_garden) self.code\_garden = code\_garden # 할 일: 구성(환경)에서\_클립보드에 읽기 def remind(self, keys: Union[str, List[str]] = None, area: Union[str, GardenArea] = None, keys\_and: bool = True, to\_clipboard=True) -> Dict[str, CodeFragment]: # 1단계: 키 파싱 keys가 None이면 keys = ['remind'] keys = self.\_parse\_keys(keys) # 2단계: 코드 찾기 code\_fragments = self.code\_garden.find(keys, area, keys\_and) # 3단계: 형식화된 코드 작성 res = "" for code\_fragment in sorted(code\_fragments.values(), 키=람다 x: x.영역.값): res += f"# {code\_fragment.name}" res += f"{code\_fragment.code}" res += f"\n\n" # 할 일: jupyter용 형식화된 코드 # 4단계: 코드를 클립보드에 복사하기 if to\_clipboard: pyperclip.copy(res) 반환 res 정적 메서드 def \_parse\_keys(keys): if isinstance(keys, str): keys = keys.split('.') 반환 키 find = remind def plant(self, code, tagline, area: Union[str, GardenArea] = GardenArea.inbox, force=False): # 1단계: 태그 라인 파싱 태그 라인에 '/'가 있으면 area, tagline = tagline.rsplit('/', 1) tags = self.\_parse\_tagline(tagline) # 2단계: 코드 저장 self.code\_garden.save( 코드, 태그, 영역, 강제=강제 ) def \_parse\_tagline(self, tagline): return tagline.split('.') add = plant def generate\_summary(self): summary = "" # 태그별로 요약 생성(가장 많이 사용됨) summary += self.code\_garden.\_generate\_summary\_by\_tag() # 할일: 사용량별 요약 생성(가장 많이 방문한/가장 적게 방문한) # 할일: 생성 날짜별 요약 생성(가장 최근 몇 개) # 할 일: 다른 것? 가장 중요한 코드를 강조하려면 어떻게 해야 하나요? # 만약을 대비해 무작위 항목? :) 요약 반환 # 할 일: 직관적인 이름 찾기 # 할일: 추가할 섹션 # 섹션 1: 하우스키핑 - 받은 편지함 정렬 등 # 섹션 2 : 카테고리 추가, AI로 생성, 요약에 사용 # 섹션 3: 로깅 추가, 요약에 사용 # 섹션 4 : 개념, 시작시 동기화, 저장시 동기화 # def housekeeping(self): # """정원을 살펴보고 식물 이름을 확인""" # 1) 먼저 메인, 받은 편지함, 보조로 시작합니다. # # 2) 완료, 완료 시간 표시 # # 3) 재방문 # 4) 전 세계적으로 모든 것을 다시 방문하십시오. # 5) 개수 및 소개와 함께 글로벌 태그 레지스트리를 유지합니다.