diff --git a/opencodeblocks/__init__.py b/opencodeblocks/__init__.py index 1de73c48..8b299e47 100644 --- a/opencodeblocks/__init__.py +++ b/opencodeblocks/__init__.py @@ -4,6 +4,6 @@ """ OpenCodeBlocks: An open-source tool for modular visual programing in python """ -__appname__ = 'OpenCodeBlocks' -__author__ = 'Mathïs Fédérico' -__version__ = '0.0.1' +__appname__ = "OpenCodeBlocks" +__author__ = "Mathïs Fédérico" +__version__ = "0.0.1" diff --git a/opencodeblocks/blocks/block.py b/opencodeblocks/blocks/block.py index 29763b57..d5a3563b 100644 --- a/opencodeblocks/blocks/block.py +++ b/opencodeblocks/blocks/block.py @@ -162,8 +162,7 @@ def get_socket_pos(self, socket: OCBSocket) -> Tuple[float]: y = y_offset else: side_lenght = self.height - y_offset - 2 * socket.radius - self.edge_size - y = y_offset + side_lenght * \ - sockets.index(socket) / (len(sockets) - 1) + y = y_offset + side_lenght * sockets.index(socket) / (len(sockets) - 1) return x, y def update_sockets(self): diff --git a/opencodeblocks/blocks/codeblock.py b/opencodeblocks/blocks/codeblock.py index f2dad9a0..e6681a22 100644 --- a/opencodeblocks/blocks/codeblock.py +++ b/opencodeblocks/blocks/codeblock.py @@ -88,16 +88,14 @@ def init_run_button(self): """Initialize the run button""" run_button = QPushButton(">", self.root) run_button.move(int(self.edge_size), int(self.edge_size / 2)) - run_button.setFixedSize(int(3 * self.edge_size), - int(3 * self.edge_size)) + run_button.setFixedSize(int(3 * self.edge_size), int(3 * self.edge_size)) run_button.clicked.connect(self.run_left) return run_button def init_run_all_button(self): """Initialize the run all button""" run_all_button = QPushButton(">>", self.root) - run_all_button.setFixedSize( - int(3 * self.edge_size), int(3 * self.edge_size)) + run_all_button.setFixedSize(int(3 * self.edge_size), int(3 * self.edge_size)) run_all_button.clicked.connect(self.run_right) run_all_button.raise_() @@ -141,7 +139,7 @@ def has_output(self) -> bool: return False def _interrupt_execution(self): - """ Interrupt an execution, reset the blocks in the queue """ + """Interrupt an execution, reset the blocks in the queue""" for block, _ in self.source_editor.kernel.execution_queue: # Reset the blocks that have not been run block.reset_buttons() @@ -200,13 +198,12 @@ def run_right(self): # Same as run_left but instead of running the blocks, we'll use run_left graph = self.scene().create_graph() edges = bfs_edges(graph, self) - blocks_to_run: List["OCBCodeBlock"] = [ - self] + [v for _, v in edges] + blocks_to_run: List["OCBCodeBlock"] = [self] + [v for _, v in edges] for block in blocks_to_run[::-1]: block.run_left(in_right_button=True) def reset_has_been_run(self): - """ Reset has_been_run, is called when the output is an error """ + """Reset has_been_run, is called when the output is an error""" self.has_been_run = False def update_title(self): diff --git a/opencodeblocks/blocks/drawingblock.py b/opencodeblocks/blocks/drawingblock.py index f45cfc62..98794f5f 100644 --- a/opencodeblocks/blocks/drawingblock.py +++ b/opencodeblocks/blocks/drawingblock.py @@ -14,10 +14,10 @@ class DrawableWidget(QWidget): - """ A drawable widget is a canvas like widget on which you can doodle """ + """A drawable widget is a canvas like widget on which you can doodle""" def __init__(self, parent: QWidget): - """ Create a new Drawable widget """ + """Create a new Drawable widget""" super().__init__(parent) self.setAttribute(Qt.WA_PaintOnScreen) self.pixel_width = 24 @@ -31,13 +31,13 @@ def __init__(self, parent: QWidget): self.color_buffer[-1].append(0xFFFFFFFF) def clearDrawing(self): - """ Clear the drawing """ + """Clear the drawing""" for i in range(self.pixel_width): for j in range(self.pixel_height): self.color_buffer[i][j] = 0xFFFFFFFF def paintEvent(self, evt: QPaintEvent): - """ Draw the content of the widget """ + """Draw the content of the widget""" painter = QPainter(self) for i in range(self.pixel_width): @@ -50,11 +50,11 @@ def paintEvent(self, evt: QPaintEvent): h * j, w + eps, h + eps, - QColor.fromRgb( - self.color_buffer[i][j])) + QColor.fromRgb(self.color_buffer[i][j]), + ) def mouseMoveEvent(self, evt: QMouseEvent): - """ Change the drawing when dragging the mouse around""" + """Change the drawing when dragging the mouse around""" if self.mouse_down: x = floor(evt.x() / self.width() * self.pixel_width) y = floor(evt.y() / self.height() * self.pixel_height) @@ -63,35 +63,36 @@ def mouseMoveEvent(self, evt: QMouseEvent): self.repaint() def mousePressEvent(self, evt: QMouseEvent): - """ Signal that the drawing starts """ + """Signal that the drawing starts""" self.mouse_down = True def mouseReleaseEvent(self, evt: QMouseEvent): - """ Signal that the drawing stops """ + """Signal that the drawing stops""" self.mouse_down = False class OCBDrawingBlock(OCBBlock): - """ An OCBBlock on which you can draw, to test your CNNs for example""" + """An OCBBlock on which you can draw, to test your CNNs for example""" def __init__(self, **kwargs): - """ Create a new OCBBlock""" + """Create a new OCBBlock""" super().__init__(**kwargs) self.draw_area = DrawableWidget(self.root) self.splitter.addWidget(self.draw_area) # QGraphicsView self.run_button = QPushButton("Clear", self.root) - self.run_button.move(int(self.edge_size * 2), - int(self.title_widget.height() + self.edge_size * 2)) - self.run_button.setFixedSize( - int(8 * self.edge_size), int(3 * self.edge_size)) + self.run_button.move( + int(self.edge_size * 2), + int(self.title_widget.height() + self.edge_size * 2), + ) + self.run_button.setFixedSize(int(8 * self.edge_size), int(3 * self.edge_size)) self.run_button.clicked.connect(self.draw_area.clearDrawing) self.holder.setWidget(self.root) @property def drawing(self): - """ A json-encoded representation of the drawing """ + """A json-encoded representation of the drawing""" return json.dumps(self.draw_area.color_buffer) @drawing.setter @@ -99,16 +100,17 @@ def drawing(self, value: str): self.draw_area.color_buffer = json.loads(value) def serialize(self): - """ Return a serialized version of this widget """ + """Return a serialized version of this widget""" base_dict = super().serialize() base_dict["drawing"] = self.drawing return base_dict - def deserialize(self, data: OrderedDict, - hashmap: dict = None, restore_id: bool = True): - """ Restore a markdown block from it's serialized state """ - for dataname in ['drawing']: + def deserialize( + self, data: OrderedDict, hashmap: dict = None, restore_id: bool = True + ): + """Restore a markdown block from it's serialized state""" + for dataname in ["drawing"]: if dataname in data: setattr(self, dataname, data[dataname]) diff --git a/opencodeblocks/blocks/markdownblock.py b/opencodeblocks/blocks/markdownblock.py index 9b3416d5..7c953b00 100644 --- a/opencodeblocks/blocks/markdownblock.py +++ b/opencodeblocks/blocks/markdownblock.py @@ -14,11 +14,11 @@ class OCBMarkdownBlock(OCBBlock): - """ A block that is able to render markdown text """ + """A block that is able to render markdown text""" def __init__(self, **kwargs): """ - Create a new OCBMarkdownBlock, a block that renders markdown + Create a new OCBMarkdownBlock, a block that renders markdown """ super().__init__(**kwargs) @@ -46,13 +46,14 @@ def __init__(self, **kwargs): self.rendered_markdown = QWebEngineView() self.rendered_markdown.page().setBackgroundColor( - QColor.fromRgba64(0, 0, 0, alpha=0)) + QColor.fromRgba64(0, 0, 0, alpha=0) + ) self.splitter.addWidget(self.rendered_markdown) self.holder.setWidget(self.root) def valueChanged(self): - """ Update markdown rendering when the content of the markdown editor changes """ + """Update markdown rendering when the content of the markdown editor changes""" t = self.editor.text() dark_theme = """ @@ -68,7 +69,7 @@ def valueChanged(self): @property def text(self) -> str: - """ The content of the markdown block """ + """The content of the markdown block""" return self.editor.text() @text.setter @@ -82,10 +83,11 @@ def serialize(self): return base_dict - def deserialize(self, data: OrderedDict, - hashmap: dict = None, restore_id: bool = True): - """ Restore a markdown block from it's serialized state """ - for dataname in ['text']: + def deserialize( + self, data: OrderedDict, hashmap: dict = None, restore_id: bool = True + ): + """Restore a markdown block from it's serialized state""" + for dataname in ["text"]: if dataname in data: setattr(self, dataname, data[dataname]) diff --git a/opencodeblocks/core/serializable.py b/opencodeblocks/core/serializable.py index bc714a78..4ed6505d 100644 --- a/opencodeblocks/core/serializable.py +++ b/opencodeblocks/core/serializable.py @@ -13,7 +13,6 @@ class Serializable: MANDATORY_FIELDS: OrderedDict = {} DEFAULT_DATA: Set[str] = {} - def __init__(self): self.id = id(self) diff --git a/opencodeblocks/graphics/edge.py b/opencodeblocks/graphics/edge.py index 4376779e..7c636917 100644 --- a/opencodeblocks/graphics/edge.py +++ b/opencodeblocks/graphics/edge.py @@ -25,7 +25,7 @@ class OCBEdge(QGraphicsPathItem, Serializable): def __init__( self, edge_width: float = 4.0, - path_type = DEFAULT_DATA["path_type"], + path_type=DEFAULT_DATA["path_type"], edge_color="#001000", edge_selected_color="#00ff00", source: QPointF = QPointF(0, 0), diff --git a/opencodeblocks/graphics/function_parsing.py b/opencodeblocks/graphics/function_parsing.py index 7c18b9ac..4af206a1 100644 --- a/opencodeblocks/graphics/function_parsing.py +++ b/opencodeblocks/graphics/function_parsing.py @@ -1,4 +1,3 @@ - """ Module for code parsing and code execution """ from typing import List, Tuple @@ -119,11 +118,11 @@ def execute_function(code: str, *args, **kwargs) -> str: """ function_name = get_function_name(code) - execution_code = f'{function_name}(' + execution_code = f"{function_name}(" for arg in args: - execution_code += f'{arg},' + execution_code += f"{arg}," for name, value in kwargs.items(): - execution_code += f'{name}={value},' + execution_code += f"{name}={value}," run_cell(code) - return run_cell(execution_code + ')') + return run_cell(execution_code + ")") diff --git a/opencodeblocks/graphics/kernel.py b/opencodeblocks/graphics/kernel.py index c5a1f509..3114e0a8 100644 --- a/opencodeblocks/graphics/kernel.py +++ b/opencodeblocks/graphics/kernel.py @@ -1,4 +1,3 @@ - """ Module to create and manage ipython kernels """ import queue @@ -8,7 +7,7 @@ from opencodeblocks.graphics.worker import Worker -class Kernel(): +class Kernel: """jupyter_client kernel used to execute code and return output""" @@ -28,31 +27,31 @@ def message_to_output(self, message: dict) -> Tuple[str, str]: single output found in the message in that order of priority: image > text data > text print > error > nothing """ - message_type = 'None' - if 'data' in message: - if 'image/png' in message['data']: - message_type = 'image' + message_type = "None" + if "data" in message: + if "image/png" in message["data"]: + message_type = "image" # output an image (from plt.plot or plt.imshow) - out = message['data']['image/png'] - elif 'text/html' in message['data']: - message_type = 'text' + out = message["data"]["image/png"] + elif "text/html" in message["data"]: + message_type = "text" # output some html text (like a pandas dataframe) - out = message['data']['text/html'] + out = message["data"]["text/html"] else: - message_type = 'text' + message_type = "text" # output data as str (for example if code="a=10\na") - out = message['data']['text/plain'] - elif 'name' in message and message['name'] == "stdout": - message_type = 'text' + out = message["data"]["text/plain"] + elif "name" in message and message["name"] == "stdout": + message_type = "text" # output a print (print("Hello World")) - out = message['text'] - elif 'traceback' in message: - message_type = 'error' + out = message["text"] + elif "traceback" in message: + message_type = "error" # output an error - out = '\n'.join(message['traceback']) + out = "\n".join(message["traceback"]) else: - message_type = 'text' - out = '' + message_type = "text" + out = "" return out, message_type def run_block(self, block, code: str): @@ -73,7 +72,7 @@ def run_block(self, block, code: str): block.source_editor.threadpool.start(worker) def run_queue(self): - """ Runs the next code in the queue """ + """Runs the next code in the queue""" self.busy = True if self.execution_queue == []: self.busy = False @@ -114,8 +113,8 @@ def get_message(self) -> Tuple[str, bool]: """ done = False try: - message = self.client.get_iopub_msg(timeout=1000)['content'] - if 'execution_state' in message and message['execution_state'] == 'idle': + message = self.client.get_iopub_msg(timeout=1000)["content"] + if "execution_state" in message and message["execution_state"] == "idle": done = True except queue.Empty: message = None diff --git a/opencodeblocks/graphics/theme.py b/opencodeblocks/graphics/theme.py index 57171f3f..30182858 100644 --- a/opencodeblocks/graphics/theme.py +++ b/opencodeblocks/graphics/theme.py @@ -9,7 +9,7 @@ class Theme: - """ Class holding the details of a specific theme""" + """Class holding the details of a specific theme""" def __init__(self, name: str, json_str: str = "{}"): """ @@ -23,7 +23,7 @@ def __init__(self, name: str, json_str: str = "{}"): "keyword_color": "#569CD6", "classname_color": "#4EC9B0", "literal_color": "#7FB347", - "operator_color": "#D8D8D8" + "operator_color": "#D8D8D8", } for (property_name, property_value) in known_properties.items(): if property_name in json_obj: @@ -33,7 +33,7 @@ def __init__(self, name: str, json_str: str = "{}"): self.name = name def apply_to_lexer(self, lexer: QsciLexerPython): - """ Make the given lexer follow the theme """ + """Make the given lexer follow the theme""" lexer.setDefaultPaper(QColor("#1E1E1E")) lexer.setDefaultColor(QColor("#D4D4D4")) @@ -51,16 +51,10 @@ def apply_to_lexer(self, lexer: QsciLexerPython): for string_type in string_types: lexer.setColor(QColor(self.string_color), string_type) - lexer.setColor( - QColor( - self.function_color), - QsciLexerPython.FunctionMethodName) + lexer.setColor(QColor(self.function_color), QsciLexerPython.FunctionMethodName) lexer.setColor(QColor(self.keyword_color), QsciLexerPython.Keyword) lexer.setColor(QColor(self.classname_color), QsciLexerPython.ClassName) lexer.setColor(QColor(self.literal_color), QsciLexerPython.Number) lexer.setColor(QColor(self.operator_color), QsciLexerPython.Operator) - lexer.setColor( - QColor( - self.comment_color), - QsciLexerPython.CommentBlock) + lexer.setColor(QColor(self.comment_color), QsciLexerPython.CommentBlock) lexer.setColor(QColor(self.comment_color), QsciLexerPython.Comment) diff --git a/opencodeblocks/qss/__init__.py b/opencodeblocks/qss/__init__.py index 16024f9c..208e3fc4 100644 --- a/opencodeblocks/qss/__init__.py +++ b/opencodeblocks/qss/__init__.py @@ -12,10 +12,10 @@ def loadStylesheets(filenames: List[str]): - styles = '' + styles = "" for filename in filenames: file = QFile(filename) file.open(QFile.ReadOnly | QFile.Text) stylesheet = file.readAll() - styles += "\n" + str(stylesheet, encoding='utf-8') + styles += "\n" + str(stylesheet, encoding="utf-8") QApplication.instance().setStyleSheet(styles) diff --git a/opencodeblocks/scene/clipboard.py b/opencodeblocks/scene/clipboard.py index eb2f6b65..c7fd021c 100644 --- a/opencodeblocks/scene/clipboard.py +++ b/opencodeblocks/scene/clipboard.py @@ -16,12 +16,12 @@ from opencodeblocks.graphics.view import OCBView -class SceneClipboard(): +class SceneClipboard: - """ Helper object to handle clipboard operations on an OCBScene. """ + """Helper object to handle clipboard operations on an OCBScene.""" - def __init__(self, scene:'OCBScene'): - """ Helper object to handle clipboard operations on an OCBScene. + def __init__(self, scene: "OCBScene"): + """Helper object to handle clipboard operations on an OCBScene. Args: scene: Scene reference. @@ -30,36 +30,42 @@ def __init__(self, scene:'OCBScene'): self.scene = scene def cut(self): - """ Cut the selected items and put them into clipboard. """ + """Cut the selected items and put them into clipboard.""" self._store(self._serializeSelected(delete=True)) def copy(self): - """ Copy the selected items into clipboard. """ + """Copy the selected items into clipboard.""" self._store(self._serializeSelected(delete=False)) def paste(self): - """ Paste the items in clipboard into the current scene. """ + """Paste the items in clipboard into the current scene.""" self._deserializeData(self._gatherData()) def _serializeSelected(self, delete=False) -> OrderedDict: selected_blocks, selected_edges = self.scene.sortedSelectedItems() selected_sockets = {} - for block in selected_blocks: # Gather selected sockets + # Gather selected sockets + for block in selected_blocks: for socket in block.sockets_in + block.sockets_out: selected_sockets[socket.id] = socket - for edge in selected_edges: # Filter edges that are not fully connected to selected sockets - if edge.source_socket.id not in selected_sockets or \ - edge.destination_socket.id not in selected_sockets: + # Filter edges that are not fully connected to selected sockets + for edge in selected_edges: + if ( + edge.source_socket.id not in selected_sockets + or edge.destination_socket.id not in selected_sockets + ): selected_edges.remove(edge) - data = OrderedDict([ - ('blocks', [block.serialize() for block in selected_blocks]), - ('edges', [edge.serialize() for edge in selected_edges]) - ]) + data = OrderedDict( + [ + ("blocks", [block.serialize() for block in selected_blocks]), + ("edges", [edge.serialize() for edge in selected_edges]), + ] + ) - if delete: # Remove selected items + if delete: # Remove selected items self.scene.views()[0].deleteSelected() return data @@ -67,7 +73,7 @@ def _serializeSelected(self, delete=False) -> OrderedDict: def _find_bbox_center(self, blocks_data): xmin, xmax, ymin, ymax = 0, 0, 0, 0 for block_data in blocks_data: - x, y = block_data['position'] + x, y = block_data["position"] if x < xmin: xmin = x if x > xmax: @@ -78,8 +84,9 @@ def _find_bbox_center(self, blocks_data): ymax = y return (xmin + xmax) / 2, (ymin + ymax) / 2 - def _deserializeData(self, data:OrderedDict, set_selected=True): - if data is None: return + def _deserializeData(self, data: OrderedDict, set_selected=True): + if data is None: + return hashmap = {} @@ -89,30 +96,34 @@ def _deserializeData(self, data:OrderedDict, set_selected=True): self.scene.clearSelection() # Finding pasting bbox center - bbox_center_x, bbox_center_y = self._find_bbox_center(data['blocks']) - offset_x, offset_y = mouse_pos.x() - bbox_center_x, mouse_pos.y() - bbox_center_y + bbox_center_x, bbox_center_y = self._find_bbox_center(data["blocks"]) + offset_x, offset_y = ( + mouse_pos.x() - bbox_center_x, + mouse_pos.y() - bbox_center_y, + ) # Create blocks - for block_data in data['blocks']: - block = self.scene.create_block(block_data, hashmap, restore_id = False) + for block_data in data["blocks"]: + block = self.scene.create_block(block_data, hashmap, restore_id=False) if set_selected: block.setSelected(True) block.setPos(block.x() + offset_x, block.y() + offset_y) # Create edges - for edge_data in data['edges']: + for edge_data in data["edges"]: edge = OCBEdge() edge.deserialize(edge_data, hashmap, restore_id=False) if set_selected: edge.setSelected(True) self.scene.addItem(edge) - hashmap.update({edge_data['id']: edge}) - - self.scene.history.checkpoint('Desiralized elements into scene', set_modified=True) + hashmap.update({edge_data["id"]: edge}) + self.scene.history.checkpoint( + "Desiralized elements into scene", set_modified=True + ) - def _store(self, data:OrderedDict): + def _store(self, data: OrderedDict): str_data = json.dumps(data, indent=4) QApplication.instance().clipboard().setText(str_data) diff --git a/opencodeblocks/scene/history.py b/opencodeblocks/scene/history.py index 9d82a8a1..945079fe 100644 --- a/opencodeblocks/scene/history.py +++ b/opencodeblocks/scene/history.py @@ -9,8 +9,8 @@ from opencodeblocks.scene import OCBScene -class SceneHistory(): - """ Helper object to handle undo/redo operations on an OCBScene. +class SceneHistory: + """Helper object to handle undo/redo operations on an OCBScene. Args: scene: Scene reference. @@ -18,42 +18,39 @@ class SceneHistory(): """ - def __init__(self, scene:'OCBScene', max_stack:int = 50): + def __init__(self, scene: "OCBScene", max_stack: int = 50): self.scene = scene self.history_stack = [] self.current = -1 self.max_stack = max_stack def undo(self): - """ Undo the last action by moving the current stamp backward and restoring. """ + """Undo the last action by moving the current stamp backward and restoring.""" if len(self.history_stack) > 0 and self.current > 0: self.current -= 1 self.restore() def redo(self): - """ Redo the last undone action by moving the current stamp forward and restoring. """ + """Redo the last undone action by moving the current stamp forward and restoring.""" if len(self.history_stack) > 0 and self.current + 1 < len(self.history_stack): self.current += 1 self.restore() - def checkpoint(self, description:str, set_modified=True): - """ Store a snapshot of the scene in the history stack. + def checkpoint(self, description: str, set_modified=True): + """Store a snapshot of the scene in the history stack. Args: description: Description given to this checkpoint. set_modified: Whether the scene should be considered modified. """ - history_stamp = { - 'description': description, - 'snapshot': self.scene.serialize() - } + history_stamp = {"description": description, "snapshot": self.scene.serialize()} self.store(history_stamp) if set_modified: self.scene.has_been_modified = True - def store(self, data:Any): - """ Store new data in the history stack, updating current checkpoint. + def store(self, data: Any): + """Store new data in the history stack, updating current checkpoint. Remove data that would be forward in the history stack. Args: @@ -61,18 +58,18 @@ def store(self, data:Any): """ if self.current + 1 < len(self.history_stack): - self.history_stack = self.history_stack[0:self.current+1] + self.history_stack = self.history_stack[0 : self.current + 1] self.history_stack.append(data) if len(self.history_stack) > self.max_stack: self.history_stack.pop(0) - self.current = min(self.current + 1, len(self.history_stack)-1) + self.current = min(self.current + 1, len(self.history_stack) - 1) def restore(self): - """ Restore the scene using the snapshot pointed by current in the history stack. """ + """Restore the scene using the snapshot pointed by current in the history stack.""" if len(self.history_stack) >= 0 and self.current >= 0: stamp = self.history_stack[self.current] - snapshot = stamp['snapshot'] + snapshot = stamp["snapshot"] self.scene.deserialize(snapshot) diff --git a/opencodeblocks/scene/scene.py b/opencodeblocks/scene/scene.py index d00d641c..ba1693b6 100644 --- a/opencodeblocks/scene/scene.py +++ b/opencodeblocks/scene/scene.py @@ -258,8 +258,8 @@ def deserialize( ): self.clear() hashmap = hashmap if hashmap is not None else {} - if restore_id and 'id' in data: - self.id = data['id'] + if restore_id and "id" in data: + self.id = data["id"] # Create blocks for block_data in data["blocks"]: diff --git a/tests/integration/blocks/test_codeblock.py b/tests/integration/blocks/test_codeblock.py index 7ab6b67b..db64f844 100644 --- a/tests/integration/blocks/test_codeblock.py +++ b/tests/integration/blocks/test_codeblock.py @@ -19,21 +19,20 @@ class TestCodeBlocks: - @pytest.fixture(autouse=True) def setup(self): - """ Setup reused variables. """ + """Setup reused variables.""" self.window = OCBWindow() self.ocb_widget = OCBWidget() self.subwindow = self.window.mdiArea.addSubWindow(self.ocb_widget) self.subwindow.show() def test_run_python(self, qtbot: QtBot): - """ run source code when run button is pressed. """ + """run source code when run button is pressed.""" # Add a block with the source to the window EXPRESSION = "3 + 5 * 2" - SOURCE_TEST = f'''print({EXPRESSION})''' + SOURCE_TEST = f"""print({EXPRESSION})""" expected_result = str(3 + 5 * 2) test_block = OCBCodeBlock(title="CodeBlock test", source=SOURCE_TEST) diff --git a/tests/integration/test_window.py b/tests/integration/test_window.py index 1ab0ecee..2544b81f 100644 --- a/tests/integration/test_window.py +++ b/tests/integration/test_window.py @@ -13,18 +13,17 @@ class TestWindow: - @pytest.fixture(autouse=True) def setup(self, mocker: MockerFixture): - """ Setup reused variables. """ + """Setup reused variables.""" self.window = OCBWindow() def test_window_close(self, qtbot): - """ closes """ + """closes""" self.window.close() def test_open_file(self): - """ loads files """ + """loads files""" wnd = OCBWindow() file_example_path = "./tests/assets/example_graph1.ipyg" subwnd = wnd.createNewMdiChild(os.path.abspath(file_example_path)) diff --git a/tests/unit/scene/test_clipboard.py b/tests/unit/scene/test_clipboard.py index 99739f20..d28b2087 100644 --- a/tests/unit/scene/test_clipboard.py +++ b/tests/unit/scene/test_clipboard.py @@ -15,7 +15,7 @@ class TestSerializeSelected: """SceneClipboard._serializeSelected""" @pytest.fixture(autouse=True) - def setup(self, mocker:MockerFixture): + def setup(self, mocker: MockerFixture): self.scene = mocker.MagicMock() self.view = mocker.MagicMock() @@ -44,23 +44,23 @@ def setup(self, mocker:MockerFixture): self.scene.sortedSelectedItems.return_value = self.blocks, self.edges self.clipboard = SceneClipboard(self.scene) - def test_serialize_selected_blocks(self, mocker:MockerFixture): - """ should allow for blocks serialization.""" + def test_serialize_selected_blocks(self, mocker: MockerFixture): + """should allow for blocks serialization.""" data = self.clipboard._serializeSelected() - check.equal(data['blocks'], [block.serialize() for block in self.blocks]) + check.equal(data["blocks"], [block.serialize() for block in self.blocks]) - def test_serialize_selected_edges(self, mocker:MockerFixture): - """ should allow for edges serialization.""" + def test_serialize_selected_edges(self, mocker: MockerFixture): + """should allow for edges serialization.""" data = self.clipboard._serializeSelected() - check.equal(data['edges'], [edge.serialize() for edge in self.edges]) + check.equal(data["edges"], [edge.serialize() for edge in self.edges]) - def test_serialize_partially_selected_edges(self, mocker:MockerFixture): - """ should not allow for partially selected edges serialization.""" + def test_serialize_partially_selected_edges(self, mocker: MockerFixture): + """should not allow for partially selected edges serialization.""" self.scene.sortedSelectedItems.return_value = self.blocks[0], self.edges data = self.clipboard._serializeSelected() - check.equal(data['edges'], [self.edges[0].serialize()]) + check.equal(data["edges"], [self.edges[0].serialize()]) - def test_serialize_delete(self, mocker:MockerFixture): - """ should allow for items deletion after serialization.""" + def test_serialize_delete(self, mocker: MockerFixture): + """should allow for items deletion after serialization.""" self.clipboard._serializeSelected(delete=True) check.is_true(self.view.deleteSelected.called) diff --git a/tests/unit/scene/test_function_parsing.py b/tests/unit/scene/test_function_parsing.py index d6e01cad..ec862ce4 100644 --- a/tests/unit/scene/test_function_parsing.py +++ b/tests/unit/scene/test_function_parsing.py @@ -4,12 +4,15 @@ from pytest_mock import MockerFixture import pytest_check as check -from opencodeblocks.graphics.function_parsing import (find_kwarg_index, run_cell, - get_function_name, - get_signature, - extract_args, - execute_function, - find_kwarg_index) +from opencodeblocks.graphics.function_parsing import ( + find_kwarg_index, + run_cell, + get_function_name, + get_signature, + extract_args, + execute_function, + find_kwarg_index, +) class TestFunctionParsing: @@ -17,72 +20,99 @@ class TestFunctionParsing: """Testing function_parsing functions""" def test_run_cell(self, mocker: MockerFixture): - """ Test run_cell """ - check.equal(run_cell("print(10)"), '10\n') + """Test run_cell""" + check.equal(run_cell("print(10)"), "10\n") def test_get_function_name(self, mocker: MockerFixture): - """ Test get_function_name """ - check.equal(get_function_name( - "def function():\n return 'Hello'"), 'function') - check.equal(get_function_name( - "#Hello\ndef function():\n return 'Hello'\na = 10"), 'function') - check.equal(get_function_name( - "#Hello\ndef function(a,b=10):\n return 'Hello'\na = 10"), 'function') + """Test get_function_name""" + check.equal(get_function_name("def function():\n return 'Hello'"), "function") + check.equal( + get_function_name("#Hello\ndef function():\n return 'Hello'\na = 10"), + "function", + ) + check.equal( + get_function_name( + "#Hello\ndef function(a,b=10):\n return 'Hello'\na = 10" + ), + "function", + ) def test_get_function_name_error(self, mocker: MockerFixture): - """ Return ValueError if get_function_name has wrong input """ + """Return ValueError if get_function_name has wrong input""" with pytest.raises(ValueError): get_function_name("") get_function_name("#Hello") get_function_name("def function") def test_get_signature(self, mocker: MockerFixture): - """ Test get_signature """ + """Test get_signature""" mocker.patch( - 'opencodeblocks.graphics.function_parsing.run_cell', return_value="(a, b, c=10)\n") - check.equal(get_signature( - "def function(a,b, c=10):\n return None"), "(a, b, c=10)\n") + "opencodeblocks.graphics.function_parsing.run_cell", + return_value="(a, b, c=10)\n", + ) + check.equal( + get_signature("def function(a,b, c=10):\n return None"), "(a, b, c=10)\n" + ) def test_find_kwarg_index(self, mocker: MockerFixture): - """ Test find_kwarg_index """ - check.equal(find_kwarg_index(['a', 'b', 'c=10']), 2) + """Test find_kwarg_index""" + check.equal(find_kwarg_index(["a", "b", "c=10"]), 2) check.equal(find_kwarg_index([]), 0) def test_extract_args(self, mocker: MockerFixture): - """ Test extract_args """ + """Test extract_args""" mocker.patch( - 'opencodeblocks.graphics.function_parsing.get_signature', return_value="()\n") + "opencodeblocks.graphics.function_parsing.get_signature", + return_value="()\n", + ) mocker.patch( - 'opencodeblocks.graphics.function_parsing.find_kwarg_index', return_value=0) - check.equal(extract_args( - "def function():\n return 'Hello'"), ([], [])) - mocker.patch('opencodeblocks.graphics.function_parsing.get_signature', - return_value="(a,b,c = 10)\n") + "opencodeblocks.graphics.function_parsing.find_kwarg_index", return_value=0 + ) + check.equal(extract_args("def function():\n return 'Hello'"), ([], [])) mocker.patch( - 'opencodeblocks.graphics.function_parsing.find_kwarg_index', return_value=2) - check.equal(extract_args( - "def function(a,b,c = 10):\n return 'Hello'"), (["a", "b"], ["c=10"])) + "opencodeblocks.graphics.function_parsing.get_signature", + return_value="(a,b,c = 10)\n", + ) + mocker.patch( + "opencodeblocks.graphics.function_parsing.find_kwarg_index", return_value=2 + ) + check.equal( + extract_args("def function(a,b,c = 10):\n return 'Hello'"), + (["a", "b"], ["c=10"]), + ) def test_extract_args_empty(self, mocker: MockerFixture): - """ Return a couple of empty lists if signature is empty """ - mocker.patch('opencodeblocks.graphics.function_parsing.get_signature', - return_value="()\n") + """Return a couple of empty lists if signature is empty""" + mocker.patch( + "opencodeblocks.graphics.function_parsing.get_signature", + return_value="()\n", + ) mocker.patch( - 'opencodeblocks.graphics.function_parsing.find_kwarg_index', return_value=None) - check.equal(extract_args( - "def function( ):\n return 'Hello'"), ([], [])) - mocker.patch('opencodeblocks.graphics.function_parsing.get_signature', - return_value="()\n") + "opencodeblocks.graphics.function_parsing.find_kwarg_index", + return_value=None, + ) + check.equal(extract_args("def function( ):\n return 'Hello'"), ([], [])) mocker.patch( - 'opencodeblocks.graphics.function_parsing.find_kwarg_index', return_value=None) - check.equal(extract_args( - "def function():\n return 'Hello'"), ([], [])) + "opencodeblocks.graphics.function_parsing.get_signature", + return_value="()\n", + ) + mocker.patch( + "opencodeblocks.graphics.function_parsing.find_kwarg_index", + return_value=None, + ) + check.equal(extract_args("def function():\n return 'Hello'"), ([], [])) def test_execute_function(self, mocker: MockerFixture): - """ Test execute_function """ - mocker.patch('opencodeblocks.graphics.function_parsing.get_function_name', - return_value="function") + """Test execute_function""" + mocker.patch( + "opencodeblocks.graphics.function_parsing.get_function_name", + return_value="function", + ) mocker.patch( - 'opencodeblocks.graphics.function_parsing.run_cell', return_value="Out[1]: 25\n") - check.equal(execute_function( - "def function(a,b,c=10):\n return a+b+c", 10, 5), "Out[1]: 25\n") + "opencodeblocks.graphics.function_parsing.run_cell", + return_value="Out[1]: 25\n", + ) + check.equal( + execute_function("def function(a,b,c=10):\n return a+b+c", 10, 5), + "Out[1]: 25\n", + ) diff --git a/tests/unit/scene/test_history.py b/tests/unit/scene/test_history.py index 756e39be..30fe0964 100644 --- a/tests/unit/scene/test_history.py +++ b/tests/unit/scene/test_history.py @@ -15,28 +15,28 @@ class TestUndo: """Undo""" @pytest.fixture(autouse=True) - def setup(self, mocker:MockerFixture): + def setup(self, mocker: MockerFixture): self.scene = mocker.MagicMock() self.history = SceneHistory(self.scene, max_stack=6) - self.history.history_stack = ['A', 'B', 'C', 'D'] + self.history.history_stack = ["A", "B", "C", "D"] self.history.current = 3 - def test_undo(self, mocker:MockerFixture): - """ should allow for undo without breaking the history stack.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_undo(self, mocker: MockerFixture): + """should allow for undo without breaking the history stack.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'D') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "D") self.history.undo() - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'C') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "C") check.is_true(self.history.restore.called) - def test_undo_nostack(self, mocker:MockerFixture): - """ should allow to undo without any change if the history stack is empty.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_undo_nostack(self, mocker: MockerFixture): + """should allow to undo without any change if the history stack is empty.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") self.history.history_stack = [] self.history.current = -1 @@ -47,18 +47,18 @@ def test_undo_nostack(self, mocker:MockerFixture): check.equal(self.history.current, -1) check.is_false(self.history.restore.called) - def test_undo_end_of_stack(self, mocker:MockerFixture): - """ should allow to undo without any change if at the end of the history stack.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_undo_end_of_stack(self, mocker: MockerFixture): + """should allow to undo without any change if at the end of the history stack.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") self.history.current = 0 - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'A') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "A") self.history.undo() - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'A') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "A") check.is_false(self.history.restore.called) @@ -67,28 +67,28 @@ class TestRedo: """Redo""" @pytest.fixture(autouse=True) - def setup(self, mocker:MockerFixture): + def setup(self, mocker: MockerFixture): self.scene = mocker.MagicMock() self.history = SceneHistory(self.scene, max_stack=6) - self.history.history_stack = ['A', 'B', 'C', 'D'] + self.history.history_stack = ["A", "B", "C", "D"] self.history.current = 1 - def test_redo(self, mocker:MockerFixture): - """ should allow for redo without changing the history stack.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_redo(self, mocker: MockerFixture): + """should allow for redo without changing the history stack.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'B') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "B") self.history.redo() - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'C') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "C") check.is_true(self.history.restore.called) - def test_redo_nostack(self, mocker:MockerFixture): - """ should allow to redo without any change if the history stack is empty.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_redo_nostack(self, mocker: MockerFixture): + """should allow to redo without any change if the history stack is empty.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") self.history.history_stack = [] self.history.current = -1 @@ -99,18 +99,18 @@ def test_redo_nostack(self, mocker:MockerFixture): check.equal(self.history.current, -1) check.is_false(self.history.restore.called) - def test_redo_end_of_stack(self, mocker:MockerFixture): - """ should allow to redo without any change if at the beggining of the history stack.""" - mocker.patch('opencodeblocks.scene.history.SceneHistory.restore') + def test_redo_end_of_stack(self, mocker: MockerFixture): + """should allow to redo without any change if at the beggining of the history stack.""" + mocker.patch("opencodeblocks.scene.history.SceneHistory.restore") self.history.current = 3 - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'D') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "D") self.history.redo() - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D']) - check.equal(self.history.history_stack[self.history.current], 'D') + check.equal(self.history.history_stack, ["A", "B", "C", "D"]) + check.equal(self.history.history_stack[self.history.current], "D") check.is_false(self.history.restore.called) @@ -119,39 +119,37 @@ class TestStore: """Store""" @pytest.fixture(autouse=True) - def setup(self, mocker:MockerFixture): + def setup(self, mocker: MockerFixture): self.scene = mocker.MagicMock() self.history = SceneHistory(self.scene, max_stack=6) - def test_store(self): - """ should update current while storing new data.""" - self.history.history_stack = ['A', 'B', 'C', 'D'] + """should update current while storing new data.""" + self.history.history_stack = ["A", "B", "C", "D"] self.history.current = 3 - self.history.store('E') + self.history.store("E") - check.equal(self.history.history_stack, ['A', 'B', 'C', 'D', 'E']) - check.equal(self.history.history_stack[self.history.current], 'E') + check.equal(self.history.history_stack, ["A", "B", "C", "D", "E"]) + check.equal(self.history.history_stack[self.history.current], "E") def test_store_cut(self): - """ should cut upper stack when storing new data.""" - self.history.history_stack = ['A', 'B', 'C', 'D'] + """should cut upper stack when storing new data.""" + self.history.history_stack = ["A", "B", "C", "D"] self.history.current = 2 - self.history.store('E') - - check.equal(self.history.history_stack, ['A', 'B', 'C', 'E']) - check.equal(self.history.history_stack[self.history.current], 'E') + self.history.store("E") + check.equal(self.history.history_stack, ["A", "B", "C", "E"]) + check.equal(self.history.history_stack[self.history.current], "E") def test_store_max_stack(self): - """ should forget oldests checkpoint when storing new data at maximum stack size.""" - self.history.history_stack = ['A', 'B', 'C', 'D'] + """should forget oldests checkpoint when storing new data at maximum stack size.""" + self.history.history_stack = ["A", "B", "C", "D"] self.history.current = 3 self.history.max_stack = 4 - self.history.store('E') + self.history.store("E") - check.equal(self.history.history_stack, ['B', 'C', 'D', 'E']) - check.equal(self.history.history_stack[self.history.current], 'E') + check.equal(self.history.history_stack, ["B", "C", "D", "E"]) + check.equal(self.history.history_stack[self.history.current], "E")