from __future__ import annotations import unittest from typing import Annotated, Optional from os import chdir from pathlib import Path from pydantic import Field from io import StringIO from contextlib import redirect_stdout, redirect_stderr print(__name__) print(__package__) from src.pyrestresource import ( RestResourceBase, ) from src.pyrestresource.rest_resource_walker import ( RestResourceWalkerFutureResult, RestResourceWalker_Root, RestResourceWalker_Sub_T_Dict, RestResourceWalker_Sub_RestFields, RestResourceWalker_Sub_RestResourceBase, ) testdir_path = Path(__file__).parent.resolve() chdir(testdir_path.parent.resolve()) class RestResourceWalkerFutureResult_RestFields_Test(RestResourceWalkerFutureResult[dict]): def process_future(self, result: Optional[list[dict]]) -> Optional[dict]: res = dict() res[self.source.resource_name] = False return res class RestResourceWalker_Sub_RestFields_TEST_Print(RestResourceWalker_Sub_RestFields): cls_RestResourceWalkerFutureResult = RestResourceWalkerFutureResult_RestFields_Test class RestResourceWalkerFutureResult_RestResourceBase_Test(RestResourceWalkerFutureResult[dict]): def process_future(self, result: Optional[list[dict]]) -> Optional[dict]: res = dict() res[self.source.resource_name] = dict() for subres in result: res[self.source.resource_name] = res[self.source.resource_name] | subres return res class RestResourceWalker_Sub_RestResourceBase_TEST_Print(RestResourceWalker_Sub_RestResourceBase): cls_RestResourceWalkerFutureResult = RestResourceWalkerFutureResult_RestResourceBase_Test class RestResourceWalkerFutureResult_Dict_Test(RestResourceWalkerFutureResult[dict]): def process_future(self, result: Optional[list[dict]]) -> Optional[dict]: res = dict() for subres in result: res = res | subres return res class RestResourceWalker_Sub_T_Dict_TEST_Print(RestResourceWalker_Sub_T_Dict): cls_RestResourceWalkerFutureResult = RestResourceWalkerFutureResult_Dict_Test class RestResourceWalker_Root_TEST_Print(RestResourceWalker_Root): cls_RestResourceWalker_Sub = [ RestResourceWalker_Sub_T_Dict_TEST_Print, RestResourceWalker_Sub_RestFields_TEST_Print, RestResourceWalker_Sub_RestResourceBase_TEST_Print, ] def init_classes(): class Info(RestResourceBase): version: str api_version: str class People(RestResourceBase): last_name: str class RootApp(RestResourceBase): info: Info = Field(default=Info(version="0.0.1", api_version="0.0.2")) info2: Info = Info(version="0.0.2", api_version="0.0.3") peoples: dict[str, People] = { "john": People(last_name="Doe"), "jane": People(last_name="Roe"), } test_string: str = "test value" test_string_opt: Optional[str] = None test_int: int = 42 # this add the classes to globals to allow using them later on # => this is only for uinit-testing purpose and is not needed in real use globals()[Info.__name__] = Info globals()[People.__name__] = People globals()[RootApp.__name__] = RootApp class Test_Walker_tree(unittest.TestCase): def setUp(self) -> None: chdir(testdir_path.parent.resolve()) init_classes() def test_walk_class(self): test = RestResourceWalker_Root_TEST_Print(RootApp) res = test.process() self.assertDictEqual( res, { "/": { "info": {"version": False, "api_version": False}, "info2": {"version": False, "api_version": False}, "peoples": {"last_name": False}, "test_string": False, "test_string_opt": False, "test_int": False, } }, ) def test_walk_obj(self): instRootApp = RootApp() test = RestResourceWalker_Root_TEST_Print(instRootApp) res = test.process() self.assertDictEqual( res, { "/": { "info": {"version": False, "api_version": False}, "info2": {"version": False, "api_version": False}, "peoples": {"last_name": False}, "test_string": False, "test_string_opt": False, "test_int": False, } }, ) def test_walk_obj_nested_RestResource(self): instRootApp = RootApp() test = RestResourceWalker_Root_TEST_Print(instRootApp.info) res = test.process() self.assertDictEqual( res, { "/": {"version": False, "api_version": False}, }, )