def test_on_can_run_whatever_on_failure(): def _capture_value(_, error): global on_whatever_value on_whatever_value = error + "Plus" E.failure("someError") | E.on | dict(whatever=_capture_value) assert on_whatever_value == "someErrorPlus"
def test_on_can_run_on_failure(): def _capture_value(x): global on_failure_value on_failure_value = x + "Plus" E.failure("someError") | E.on | dict(failure=_capture_value) assert on_failure_value == "someErrorPlus"
def remove_item_by_id(self, id: str) -> E.Either[str, RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute("DELETE FROM cart WHERE id = %s", [id]) rows_deleted = cursor.rowcount self.__db_conn.commit() if rows_deleted == 1: return E.success(id) return E.failure(NotFoundRepositoryException([id])) except Exception as inst: self.__db_conn.rollback() return E.failure(UnknownException(list(inst.args)))
def get_item_by_id(self, id: str) -> E.Either[CartItem, RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute( "SELECT id, name, price, manufacturer, updated_at, created_at FROM cart WHERE id = %s", [id]) row = cursor.fetchone() if row: return E.success(self.__from_tuple(row)) return E.failure(NotFoundRepositoryException()) except Exception as inst: return E.failure(UnknownException(list(inst.args)))
def convert_list_to_either( items: List[E.Either[T, Exception]]) -> E.Either[List[U], Exception]: success_results = [] for item in items: success_result, failure_result = item | E.from_either | dict( if_success=(lambda result: (result, None)), if_failure=(lambda ex: (None, ex))) if success_result is not None: success_results.append(success_result) elif failure_result is not None: return E.failure(failure_result) else: return E.failure(Exception("Unexpected error has occurred!")) return E.success(success_results)
def safely_load_json(filename: str) -> E.Either[CartItem, Exception]: with open(filename) as json_file: try: results = get_json_data(json_file) return E.success(results) except Exception as inst: return E.failure(inst)
def create_database(self) -> E.Either[CartItem, RepositoryException]: try: cursor = self.__db_conn.cursor() results = cursor.execute("CREATE DATABASE IF NOT EXISTS cart") self.__db_conn.commit() return E.success(results) except Exception as inst: self.__db_conn.rollback() return E.failure(UnknownException(list(inst.args)))
def check_connection(self) -> E.Either[str, RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute("SELECT 1;") _ = cursor.fetchone() self.__db_conn.commit() return E.success("Success!") except Exception as inst: return E.failure(UnknownException(list(inst.args)))
def update_item(self, item: CartItem) -> E.Either[CartItem, RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute( "UPDATE cart SET name = %s, price = %s, manufacturer = %s, updated_at = %s WHERE id = %s RETURNING id, name, price, manufacturer, updated_at, created_at", [ item.name, item.price, item.manufacturer, datetime.datetime.now().isoformat(), item.id ]) result = cursor.fetchone() self.__db_conn.commit() if result: return E.success(self.__from_tuple(result)) return E.failure(NotFoundRepositoryException()) except Exception as inst: self.__db_conn.rollback() return E.failure(UnknownException(list(inst.args)))
def add_item(self, item: CartItem) -> E.Either[CartItem, RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute( "INSERT INTO cart (name, price, manufacturer, updated_at, created_at) VALUES (%s, %s, %s, %s, %s) RETURNING id, name, price, manufacturer, updated_at, created_at", [ item.name, item.price, item.manufacturer, item.updated_at, item.created_at ]) result = cursor.fetchone() self.__db_conn.commit() if result: return E.success(self.__from_tuple(result)) return E.failure( UnknownException(["Unable to add item at this time!"])) except Exception as inst: self.__db_conn.rollback() return E.failure(UnknownException(list(inst.args)))
def get_all_items( self, page_number: int = 0, page_size: int = 10 ) -> E.Either[List[CartItem], RepositoryException]: try: cursor = self.__db_conn.cursor() cursor.execute( "SELECT id, name, price, manufacturer, updated_at, created_at FROM cart LIMIT %s OFFSET %s", [page_size, page_number * page_size]) rows = cursor.fetchmany(size=page_size) if rows: return E.success(list(map(self.__from_tuple, rows))) return E.success([]) except Exception as inst: return E.failure(UnknownException(list(inst.args)))
def validate(item: Dict[str, str]) -> E.Either['CartItem', Exception]: def empty_value(type: str) -> str: return f"'{type}' must not be empty" def get_optional_value(key: str, defaultValue: Any = "") -> str: if key in item: return item[key] else: return defaultValue errors: List[str] = [] if item["name"] is None: errors.append(empty_value("name")) elif len(item["name"]) == 0: errors.append(empty_value("name")) if item["price"] is None: errors.append(empty_value("price")) if int(item["price"]) < 99: errors.append("'price' must be greater than 99") if item["manufacturer"] is None: errors.append(empty_value("manufacturer")) if len(item["manufacturer"]) == 0: errors.append(empty_value("manufacturer")) if len(errors) != 0: return E.failure(InvalidItemException(errors)) else: current_timestamp = datetime.datetime.now().isoformat() return E.success(CartItem( id=get_optional_value("id"), name=item["name"], price=item["price"], manufacturer=item["manufacturer"], created_at=get_optional_value("created_at", defaultValue=current_timestamp), updated_at=get_optional_value("updated_at", defaultValue=current_timestamp) ))
def test_from_either_can_return_on_failure(): assert E.failure("someError") \ | E.from_either | dict( if_success=lambda _: "shouldSucceed", if_failure=lambda e: e + "Plus") == "someErrorPlus"
def test_can_catch_error_and_default_non_either_result_to_success(): assert E.failure("someError") | E.catch_error | ( lambda _: 1) == E.success(1)
def test_can_catch_error_and_return_success(): assert E.failure("someError") | E.catch_error | ( lambda x: E.success(1)) == E.success(1)
def test_can_catch_error_and_return_error(): assert E.failure("someError") | E.catch_error | ( lambda x: E.failure(x + "Plus")) == E.failure("someErrorPlus")
def test_can_map_error(): assert E.failure("someError") | E.map_error | ( lambda x: x + "Plus") == E.failure("someErrorPlus")
def test_can_chain_success_either_and_fail(): assert E.success(1) | E.then | ( lambda _: E.failure("someError")) == E.failure("someError")
def test_can_map_failure_either(): assert E.failure("someError") | E.map | ( lambda x: x + 1) == E.failure("someError")
def test_can_make_failure_either(): assert E.failure("someError") == ("failure", "someError")
def create_db_conn(database_uri: str) -> E.Either[Connection, RepositoryException]: try: config = parse_db_config(database_uri) return E.success(connect(host=config.host, user=config.username, password=config.password, dbname=config.name, port=config.port)) except Exception as inst: return E.failure(ConnectionFailedRepositoryException(list(inst.args)))
def __check_result(items: List[CartItem] = []) -> E.Either[List[CartItem], Exception]: if len(items) <= 0: return E.failure("No more items!") else: return E.success(items)