def test_prefix(set_env, env: Env): set_env({"PREFIX_STRING": "some string"}) assert env.str("PREFIX_STRING") == "some string" env.prefix.append("PREFIX_") assert env.str("STRING") == "some string" env.prefix.pop() assert env.str("PREFIX_STRING") == "some string"
def test_validators_that_raise(set_env, env: Env): def is_positive(val): if val <= 0: raise Exception("Number is not positive") set_env({"A_FLOAT": "982.1"}) assert env.float("A_FLOAT", validate=is_positive) == 982.1 set_env({"A_FLOAT": "-0.2"}) with pytest.raises(Exception) as exc_info: env.float("A_FLOAT", validate=is_positive) assert "Value did not pass custom validator" in str(exc_info.value) assert "A_FLOAT" in str(exc_info.value) assert str(exc_info.value.__cause__) == "Number is not positive"
def test_prefixed(set_env, env: Env): set_env({"PF1_PF2_STRING": "some string"}) assert env.str("PF1_PF2_STRING") == "some string" with env.prefixed("PF1_"): assert env.str("PF2_STRING") == "some string" with env.prefixed("PF2_"): assert env.str("STRING") == "some string" assert env.str("PF2_STRING") == "some string" assert env.str("PF1_PF2_STRING") == "some string"
def test_validators_that_return(set_env, env: Env): def is_positive(val): return val > 0 def is_negative(val): return val < 0 set_env({"AN_INTEGER": "982"}) assert env.int("AN_INTEGER", validate=is_positive) == 982 assert env.int("AN_INTEGER", validate=(is_positive, is_positive)) == 982 with pytest.raises(Exception): env.int("AN_INTEGER", validate=is_negative) with pytest.raises(Exception): env.int("AN_INTEGER", validate=(is_positive, is_negative))
def test_read_env(env: Env): assert env.read_env("./tests/.env.test") assert env.str("A_STRING") == "blabla"
def test_default_to_none(env: Env): assert env.int("THIS_IS_NOT_IN_ENV", default=None) is None
def test_upper_casing(set_env): set_env({"AN_INTEGER": "982"}) assert Env(upper=True).int("aN_iNtEgEr") == 982
def test_invalid_char_in_name(env: Env): with pytest.raises(ValueError) as exc_info: env.int("HERES_AN_INVALID_CHAR_=") err_msg = str(exc_info.value) assert "Environment variable name contains invalid character(s)" in err_msg assert "HERES_AN_INVALID_CHAR_=" in err_msg
def test_name_starts_with_number(env: Env): with pytest.raises(ValueError) as exc_info: env.int("7HIS_STARTS_WITH_NUMBER") err_msg = str(exc_info.value) assert "Environment variable name can not start with a number" in err_msg assert "7HIS_STARTS_WITH_NUMBER" in err_msg
def test_missing(env: Env): with pytest.raises(Exception) as exc_info: env.int("THIS_IS_NOT_IN_ENV") assert '"THIS_IS_NOT_IN_ENV" is missing' in str(exc_info.value)
def test_empty_str_name(env: Env): with pytest.raises(ValueError) as exc_info: env.int("") assert "Environment variable name can not be an empty string" in str(exc_info.value)
def test_dump_and_get_example(set_env, env: Env): set_env( { "VAR_1": "some string", "VAR_2": "4", "VAR_3": "4.5", "VAR_4": "True,False", "EXTRA_VAR": "dont read this", } ) env.str("VAR_1", default="some default") env.int("VAR_2") env.decimal("VAR_3") env.list("VAR_4", subcast=bool) env.json("NON_EXISTING", default={}) assert env.dump() == { "VAR_1": ParsedValue("some string", "str", True), "VAR_2": ParsedValue(4, "int", False), "VAR_3": ParsedValue(D("4.5"), "decimal", False), "VAR_4": ParsedValue([True, False], "list", False), "NON_EXISTING": ParsedValue({}, "json", True), } assert env.get_example() == ( "NON_EXISTING=Optional[json]\n" "VAR_1=Optional[str]\n" "VAR_2=int\n" "VAR_3=decimal\n" "VAR_4=list\n" )
def test_read_env__not_found(env: Env): assert not env.read_env("this-path-should-not-exist.test")
from cerbottana.connection import Connection from cerbottana.database import Database from cerbottana.models.room import Room from cerbottana.tasks.veekun import csv_to_sqlite # pylint: disable=protected-access, redefined-outer-name def pytest_collection_modifyitems(items): for item in items: # Mark tests using a real showdown instance with `pytest.mark.real_ps_instance` if "showdown_connection" in item.fixturenames: item.add_marker(pytest.mark.real_ps_instance) env = Env() env.read_env() database_metadata: dict[str, Any] = { "database": d.Base.metadata, } class ControlMessage(bytes, Enum): # server to client PROCESS_MESSAGES = b"process_messages" PROCESS_AND_REPLY = b"process_and_reply" # client to server PROCESSING_DONE = b"processing_done"
def main() -> None: def shutdown(sig: int, frame_type: FrameType | None) -> None: if conn.websocket is not None and conn.loop is not None: for task in asyncio.all_tasks(conn.loop): task.cancel() coro = conn.websocket.close() asyncio.run_coroutine_threadsafe(coro, conn.loop) env = Env() env.read_env() host = env.str("SHOWDOWN_HOST") port = env.int("SHOWDOWN_PORT") protocol = "wss" if port == 443 else "ws" url = f"{protocol}://{host}:{port}/showdown/websocket" conn = Connection( url=url, username=env.str("USERNAME"), password=env.str("PASSWORD"), avatar=env.str("AVATAR", default=""), statustext=env.str("STATUSTEXT", default=""), rooms=env.list("ROOMS", default=[]), main_room=env.str("MAIN_ROOM"), command_character=env.str("COMMAND_CHARACTER"), administrators=env.list("ADMINISTRATORS", default=[]), webhooks=env.json("WEBHOOKS", default={}), ) signal.signal(signal.SIGINT, shutdown) conn.open_connection()
def env() -> Env: return Env()