mirror of
https://github.com/infeeeee/dyn2py
synced 2025-12-16 22:16:18 +01:00
Tests, documentation, fixes
This commit is contained in:
@@ -92,11 +92,19 @@ class File():
|
||||
def write(self, options: Options) -> None:
|
||||
"""Prepare writing file to the disk:
|
||||
create backup, process dry-run, call filetype specific write_file() methods
|
||||
Should be called on subclasses!
|
||||
|
||||
Args:
|
||||
options(Options): Run options.
|
||||
|
||||
Raises:
|
||||
TypeError: If called on a File object
|
||||
"""
|
||||
|
||||
# This should only work on subclasses:
|
||||
if type(self).__name__ == "File":
|
||||
raise TypeError("This method shouldn't be called on File objects!")
|
||||
|
||||
if not self.modified:
|
||||
logging.debug("File not modified, not saving")
|
||||
return
|
||||
@@ -126,16 +134,16 @@ class DynamoFile(File):
|
||||
"""A Dynamo file, subclass of File()"""
|
||||
|
||||
full_dict: dict
|
||||
"""The contents of the Dynamo file, as dict."""
|
||||
"""The contents of the Dynamo file, as dict. Initialized with read()"""
|
||||
uuid: str
|
||||
"""The uuid of the graph"""
|
||||
"""The uuid of the graph. Initialized with read()"""
|
||||
name: str
|
||||
"""The name of the graph, read from the file. Not the name of the file"""
|
||||
"""The name of the graph, read from the file. Initialized with read()"""
|
||||
python_nodes: list["PythonNode"]
|
||||
"""Python node objects, read from this file"""
|
||||
"""Python node objects, read from this file. Initialized with get_python_nodes()"""
|
||||
|
||||
open_files: set["DynamoFile"] = set()
|
||||
"""A set of open Dynamo files, before saving"""
|
||||
"""A set of open Dynamo files, before saving. Self added by read()"""
|
||||
|
||||
def extract_python(self, options: Options | None = None) -> None:
|
||||
"""Extract and write python files
|
||||
@@ -174,6 +182,7 @@ class DynamoFile(File):
|
||||
"""Read Dynamo graph to parameters
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: The file does not exist
|
||||
DynamoFileException: If the file is a Dynamo 1 file
|
||||
json.JSONDecodeError: If there are any other problem with the file
|
||||
"""
|
||||
@@ -204,6 +213,9 @@ class DynamoFile(File):
|
||||
|
||||
Returns:
|
||||
list[PythonNode]: A list of PythonNodes in the file
|
||||
|
||||
Raises:
|
||||
DynamoFileException: If no Python nodes in the file
|
||||
"""
|
||||
if not self in self.open_files:
|
||||
self.read()
|
||||
@@ -211,8 +223,13 @@ class DynamoFile(File):
|
||||
full_python_nodes = [n for n in self.full_dict["Nodes"]
|
||||
if n["NodeType"] == "PythonScriptNode"]
|
||||
|
||||
# Check if it was already read:
|
||||
try:
|
||||
self.python_nodes
|
||||
except AttributeError:
|
||||
self.python_nodes = []
|
||||
|
||||
if not self.python_nodes:
|
||||
for p_node in full_python_nodes:
|
||||
# The name of the node is stored here:
|
||||
node_views = self.full_dict["View"]["NodeViews"]
|
||||
@@ -326,14 +343,14 @@ class PythonFile(File):
|
||||
"""A Python file, subclass of File()"""
|
||||
|
||||
code: str
|
||||
"""The python code as a string"""
|
||||
"""The python code as a string. Initialized with read()"""
|
||||
header_data: dict
|
||||
"""Parsed dict from the header of a python file"""
|
||||
"""Parsed dict from the header of a python file. Initialized with read()"""
|
||||
text: str
|
||||
"""Full contents of the file before writing"""
|
||||
"""Full contents of the file before writing. Initialized with generate_text()"""
|
||||
|
||||
open_files: set["PythonFile"] = set()
|
||||
"""A set of open Python files"""
|
||||
"""A set of open Python files. Self added by read()"""
|
||||
|
||||
def generate_text(self, dynamo_file: DynamoFile, python_node: "PythonNode") -> None:
|
||||
"""Generate full text to write with header
|
||||
@@ -348,12 +365,17 @@ class PythonFile(File):
|
||||
Do not edit this section, if you want to update the Dynamo graph!\
|
||||
"""
|
||||
|
||||
# Double escape path:
|
||||
dyn_path_string = str(dynamo_file.realpath)
|
||||
if "\\" in dyn_path_string:
|
||||
dyn_path_string = dyn_path_string.replace("\\", "\\\\")
|
||||
|
||||
self.header_data = {
|
||||
"dyn2py_version": METADATA["Version"],
|
||||
"dyn2py_extracted": datetime.now().isoformat(),
|
||||
"dyn_uuid": dynamo_file.uuid,
|
||||
"dyn_name": dynamo_file.name,
|
||||
"dyn_path": dynamo_file.realpath,
|
||||
"dyn_path": dyn_path_string,
|
||||
"dyn_modified": dynamo_file.mtimeiso,
|
||||
"py_id": python_node.id,
|
||||
"py_engine": python_node.engine
|
||||
@@ -486,7 +508,7 @@ class PythonFile(File):
|
||||
|
||||
def write_file(self) -> None:
|
||||
"""Write this file to the disk. Should be called only from File.write()"""
|
||||
with open(self.filepath, "w", encoding="utf-8") as output_file:
|
||||
with open(self.filepath, "w", encoding="utf-8", newline='') as output_file:
|
||||
output_file.write(self.text)
|
||||
|
||||
|
||||
|
||||
200
tests/input_files/no_python.dyn
Normal file
200
tests/input_files/no_python.dyn
Normal file
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"Uuid": "76de5c79-17c5-4c74-9f90-ad99a213d339",
|
||||
"IsCustomNode": false,
|
||||
"Description": "",
|
||||
"Name": "no_python",
|
||||
"ElementResolver": {
|
||||
"ResolutionMap": {}
|
||||
},
|
||||
"Inputs": [],
|
||||
"Outputs": [],
|
||||
"Nodes": [
|
||||
{
|
||||
"ConcreteType": "Dynamo.Graph.Nodes.ZeroTouch.DSFunction, DynamoCore",
|
||||
"NodeType": "FunctionNode",
|
||||
"FunctionSignature": "+@var[]..[],var[]..[]",
|
||||
"Id": "f8f4d3310211429ea8f301284983849e",
|
||||
"Inputs": [
|
||||
{
|
||||
"Id": "264e2d2a3442445180048463a555399a",
|
||||
"Name": "x",
|
||||
"Description": "Integer value, double value or string\n\nvar[]..[]",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
},
|
||||
{
|
||||
"Id": "f627c4088ee943aeba708e81f9945f1e",
|
||||
"Name": "y",
|
||||
"Description": "Integer value, double value or string\n\nvar[]..[]",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Outputs": [
|
||||
{
|
||||
"Id": "72975df34c2542ff949630ef7253bed5",
|
||||
"Name": "var",
|
||||
"Description": "The sum of two input numbers, or the concatenation of two strings",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Replication": "Auto",
|
||||
"Description": "Returns addition of x and y\n\n+ (x: var[]..[], y: var[]..[]): var[]..[]"
|
||||
},
|
||||
{
|
||||
"ConcreteType": "Dynamo.Graph.Nodes.CodeBlockNodeModel, DynamoCore",
|
||||
"NodeType": "CodeBlockNode",
|
||||
"Code": "1;",
|
||||
"Id": "24cee4b3934f46309d34386a1b5a674a",
|
||||
"Inputs": [],
|
||||
"Outputs": [
|
||||
{
|
||||
"Id": "dffa5271656d49e0b61ba8133b92a05e",
|
||||
"Name": "",
|
||||
"Description": "Value of expression at line 1",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Replication": "Disabled",
|
||||
"Description": "Allows for DesignScript code to be authored directly"
|
||||
},
|
||||
{
|
||||
"ConcreteType": "CoreNodeModels.Watch, CoreNodeModels",
|
||||
"NodeType": "ExtensionNode",
|
||||
"Id": "26fc878922fd425a89112c6b14c9779b",
|
||||
"Inputs": [
|
||||
{
|
||||
"Id": "1587eb8d7d8f41e6833e2b90f95b63fb",
|
||||
"Name": "",
|
||||
"Description": "Node to show output from",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Outputs": [
|
||||
{
|
||||
"Id": "d70e73be40114b9cb129a91cd4777c4a",
|
||||
"Name": "",
|
||||
"Description": "Node output",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Replication": "Disabled",
|
||||
"Description": "Visualizes a node's output"
|
||||
}
|
||||
],
|
||||
"Connectors": [
|
||||
{
|
||||
"Start": "72975df34c2542ff949630ef7253bed5",
|
||||
"End": "1587eb8d7d8f41e6833e2b90f95b63fb",
|
||||
"Id": "8d017b34cb5b47f1b900c1c6ed8fd8d0",
|
||||
"IsHidden": "False"
|
||||
},
|
||||
{
|
||||
"Start": "dffa5271656d49e0b61ba8133b92a05e",
|
||||
"End": "264e2d2a3442445180048463a555399a",
|
||||
"Id": "46f9099ffb1a4e08ad78d7e13d36d8bc",
|
||||
"IsHidden": "False"
|
||||
},
|
||||
{
|
||||
"Start": "dffa5271656d49e0b61ba8133b92a05e",
|
||||
"End": "f627c4088ee943aeba708e81f9945f1e",
|
||||
"Id": "f167bc9b5eed4d5c96bac03015664979",
|
||||
"IsHidden": "False"
|
||||
}
|
||||
],
|
||||
"Dependencies": [],
|
||||
"NodeLibraryDependencies": [],
|
||||
"Thumbnail": "",
|
||||
"GraphDocumentationURL": null,
|
||||
"ExtensionWorkspaceData": [
|
||||
{
|
||||
"ExtensionGuid": "28992e1d-abb9-417f-8b1b-05e053bee670",
|
||||
"Name": "Properties",
|
||||
"Version": "2.17",
|
||||
"Data": {}
|
||||
}
|
||||
],
|
||||
"Author": "",
|
||||
"Linting": {
|
||||
"activeLinter": "None",
|
||||
"activeLinterId": "7b75fb44-43fd-4631-a878-29f4d5d8399a",
|
||||
"warningCount": 0,
|
||||
"errorCount": 0
|
||||
},
|
||||
"Bindings": [],
|
||||
"View": {
|
||||
"Dynamo": {
|
||||
"ScaleFactor": 1.0,
|
||||
"HasRunWithoutCrash": true,
|
||||
"IsVisibleInDynamoLibrary": true,
|
||||
"Version": "2.17.0.3472",
|
||||
"RunType": "Automatic",
|
||||
"RunPeriod": "1000"
|
||||
},
|
||||
"Camera": {
|
||||
"Name": "_Background Preview",
|
||||
"EyeX": -17.0,
|
||||
"EyeY": 24.0,
|
||||
"EyeZ": 50.0,
|
||||
"LookX": 12.0,
|
||||
"LookY": -13.0,
|
||||
"LookZ": -58.0,
|
||||
"UpX": 0.0,
|
||||
"UpY": 1.0,
|
||||
"UpZ": 0.0
|
||||
},
|
||||
"ConnectorPins": [],
|
||||
"NodeViews": [
|
||||
{
|
||||
"Name": "+",
|
||||
"ShowGeometry": true,
|
||||
"Id": "f8f4d3310211429ea8f301284983849e",
|
||||
"IsSetAsInput": false,
|
||||
"IsSetAsOutput": false,
|
||||
"Excluded": false,
|
||||
"X": 779.0,
|
||||
"Y": 566.5
|
||||
},
|
||||
{
|
||||
"Name": "Code Block",
|
||||
"ShowGeometry": true,
|
||||
"Id": "24cee4b3934f46309d34386a1b5a674a",
|
||||
"IsSetAsInput": false,
|
||||
"IsSetAsOutput": false,
|
||||
"Excluded": false,
|
||||
"X": 402.0,
|
||||
"Y": 500.0
|
||||
},
|
||||
{
|
||||
"Name": "Watch",
|
||||
"ShowGeometry": true,
|
||||
"Id": "26fc878922fd425a89112c6b14c9779b",
|
||||
"IsSetAsInput": false,
|
||||
"IsSetAsOutput": false,
|
||||
"Excluded": false,
|
||||
"X": 1102.0,
|
||||
"Y": 587.0
|
||||
}
|
||||
],
|
||||
"Annotations": [],
|
||||
"X": 127.12026168573345,
|
||||
"Y": 129.76719880218047,
|
||||
"Zoom": 0.7658293928515516
|
||||
}
|
||||
}
|
||||
106
tests/input_files/single_node.dyn
Normal file
106
tests/input_files/single_node.dyn
Normal file
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"Uuid": "76de5c79-17c5-4c74-9f90-ad99a213d339",
|
||||
"IsCustomNode": false,
|
||||
"Description": "",
|
||||
"Name": "single_node",
|
||||
"ElementResolver": {
|
||||
"ResolutionMap": {}
|
||||
},
|
||||
"Inputs": [],
|
||||
"Outputs": [],
|
||||
"Nodes": [
|
||||
{
|
||||
"ConcreteType": "PythonNodeModels.PythonNode, PythonNodeModels",
|
||||
"NodeType": "PythonScriptNode",
|
||||
"Code": "# Load the Python Standard and DesignScript Libraries\r\nimport sys\r\nimport clr\r\nclr.AddReference('ProtoGeometry')\r\nfrom Autodesk.DesignScript.Geometry import *\r\n\r\n# The inputs to this node will be stored as a list in the IN variables.\r\ndataEnteringNode = IN\r\n\r\noutput = {\r\n \"python_version\": sys.version,\r\n \"asd_string\": \"asd_string\"\r\n}\r\n\r\n\r\n# Assign your output to the OUT variable.\r\nOUT = output",
|
||||
"Engine": "CPython3",
|
||||
"EngineName": "CPython3",
|
||||
"VariableInputPorts": true,
|
||||
"Id": "1c5d99792882409e97e132b3e9f814b0",
|
||||
"Inputs": [
|
||||
{
|
||||
"Id": "7a29134d5d35492b80cd49a3ebac1847",
|
||||
"Name": "IN[0]",
|
||||
"Description": "Input #0",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Outputs": [
|
||||
{
|
||||
"Id": "a6a87605c777416bb759eaa87c976285",
|
||||
"Name": "OUT",
|
||||
"Description": "Result of the python script",
|
||||
"UsingDefaultValue": false,
|
||||
"Level": 2,
|
||||
"UseLevels": false,
|
||||
"KeepListStructure": false
|
||||
}
|
||||
],
|
||||
"Replication": "Disabled",
|
||||
"Description": "Runs an embedded Python script."
|
||||
}
|
||||
],
|
||||
"Connectors": [],
|
||||
"Dependencies": [],
|
||||
"NodeLibraryDependencies": [],
|
||||
"Thumbnail": "",
|
||||
"GraphDocumentationURL": null,
|
||||
"ExtensionWorkspaceData": [
|
||||
{
|
||||
"ExtensionGuid": "28992e1d-abb9-417f-8b1b-05e053bee670",
|
||||
"Name": "Properties",
|
||||
"Version": "2.17",
|
||||
"Data": {}
|
||||
}
|
||||
],
|
||||
"Author": "",
|
||||
"Linting": {
|
||||
"activeLinter": "None",
|
||||
"activeLinterId": "7b75fb44-43fd-4631-a878-29f4d5d8399a",
|
||||
"warningCount": 0,
|
||||
"errorCount": 0
|
||||
},
|
||||
"Bindings": [],
|
||||
"View": {
|
||||
"Dynamo": {
|
||||
"ScaleFactor": 1.0,
|
||||
"HasRunWithoutCrash": true,
|
||||
"IsVisibleInDynamoLibrary": true,
|
||||
"Version": "2.17.0.3472",
|
||||
"RunType": "Automatic",
|
||||
"RunPeriod": "1000"
|
||||
},
|
||||
"Camera": {
|
||||
"Name": "_Background Preview",
|
||||
"EyeX": -17.0,
|
||||
"EyeY": 24.0,
|
||||
"EyeZ": 50.0,
|
||||
"LookX": 12.0,
|
||||
"LookY": -13.0,
|
||||
"LookZ": -58.0,
|
||||
"UpX": 0.0,
|
||||
"UpY": 1.0,
|
||||
"UpZ": 0.0
|
||||
},
|
||||
"ConnectorPins": [],
|
||||
"NodeViews": [
|
||||
{
|
||||
"Name": "Python Script",
|
||||
"ShowGeometry": true,
|
||||
"Id": "1c5d99792882409e97e132b3e9f814b0",
|
||||
"IsSetAsInput": false,
|
||||
"IsSetAsOutput": false,
|
||||
"Excluded": false,
|
||||
"X": 208.0,
|
||||
"Y": 367.0
|
||||
}
|
||||
],
|
||||
"Annotations": [],
|
||||
"X": 84.425000000000011,
|
||||
"Y": -8.4125000000000227,
|
||||
"Zoom": 1.1575
|
||||
}
|
||||
}
|
||||
12
tests/support.py
Normal file
12
tests/support.py
Normal file
@@ -0,0 +1,12 @@
|
||||
import pathlib
|
||||
|
||||
INPUT_DIR = "tests/input_files"
|
||||
OUTPUT_DIR = "tests/output_files"
|
||||
|
||||
def cleanup_output_dir():
|
||||
output_dir = pathlib.Path(OUTPUT_DIR)
|
||||
if output_dir.exists():
|
||||
for f in output_dir.iterdir():
|
||||
f.unlink()
|
||||
else:
|
||||
output_dir.mkdir()
|
||||
@@ -1,6 +1,5 @@
|
||||
import unittest
|
||||
import subprocess
|
||||
import platform
|
||||
|
||||
|
||||
class TestCommandLine(unittest.TestCase):
|
||||
|
||||
@@ -2,16 +2,8 @@ import unittest
|
||||
import dyn2py
|
||||
import pathlib
|
||||
|
||||
INPUT_DIR = "tests/input_files"
|
||||
OUTPUT_DIR = "tests/output_files"
|
||||
from tests.support import *
|
||||
|
||||
def cleanup_output_dir():
|
||||
output_dir = pathlib.Path(OUTPUT_DIR)
|
||||
if output_dir.exists():
|
||||
for f in output_dir.iterdir():
|
||||
f.unlink()
|
||||
else:
|
||||
output_dir.mkdir()
|
||||
|
||||
class TestDynamoFile(unittest.TestCase):
|
||||
|
||||
@@ -21,7 +13,7 @@ class TestDynamoFile(unittest.TestCase):
|
||||
# update_python_node
|
||||
# write
|
||||
|
||||
def test_read(self):
|
||||
def test_read_and_variables(self):
|
||||
dyn = dyn2py.DynamoFile(f"{INPUT_DIR}/python_nodes.dyn")
|
||||
dyn.read()
|
||||
|
||||
@@ -38,7 +30,7 @@ class TestDynamoFile(unittest.TestCase):
|
||||
dyn2.read()
|
||||
|
||||
|
||||
def test_get_python_node(self):
|
||||
def test_get_python_nodes(self):
|
||||
dyn = dyn2py.DynamoFile(f"{INPUT_DIR}/python_nodes.dyn")
|
||||
py_nodes = dyn.get_python_nodes()
|
||||
py_node = dyn.get_python_node_by_id("d7704617c75e4bf1a5c387b7c3f001ea")
|
||||
@@ -46,11 +38,19 @@ class TestDynamoFile(unittest.TestCase):
|
||||
self.assertEqual(len(py_nodes), 6)
|
||||
self.assertTrue(py_node)
|
||||
self.assertTrue(py_node in py_nodes)
|
||||
self.assertTrue(py_node in dyn.python_nodes)
|
||||
self.assertEqual(py_node.checksum, "1f3d9e6153804fe1ed37571a9cda8e26")
|
||||
|
||||
with self.assertRaises(dyn2py.PythonNodeNotFoundException):
|
||||
dyn.get_python_node_by_id("wrongid")
|
||||
|
||||
dyn2 = dyn2py.DynamoFile(f"{INPUT_DIR}/no_python.dyn")
|
||||
|
||||
# Raise error on file without python nodes:
|
||||
with self.assertRaises(dyn2py.DynamoFileException):
|
||||
dyn2.get_python_nodes()
|
||||
|
||||
|
||||
def test_extract_python(self):
|
||||
cleanup_output_dir()
|
||||
|
||||
|
||||
92
tests/test_File.py
Normal file
92
tests/test_File.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import unittest
|
||||
import dyn2py
|
||||
import pathlib
|
||||
import platform
|
||||
|
||||
from tests.support import *
|
||||
|
||||
|
||||
class TestFile(unittest.TestCase):
|
||||
|
||||
# Methods to test:
|
||||
# is_dynamo_file
|
||||
# is_python_file
|
||||
|
||||
def test_init(self):
|
||||
paths = [
|
||||
f"{INPUT_DIR}/python_nodes.dyn",
|
||||
pathlib.Path(f"{INPUT_DIR}/python_nodes.dyn")
|
||||
]
|
||||
|
||||
if platform.system() == "Windows":
|
||||
paths.extend([
|
||||
fr"{INPUT_DIR}\python_nodes.dyn",
|
||||
pathlib.Path(fr"{INPUT_DIR}\python_nodes.dyn")
|
||||
])
|
||||
|
||||
for path in paths:
|
||||
the_file = dyn2py.File(path)
|
||||
|
||||
self.assertEqual(the_file.filepath,
|
||||
pathlib.Path(f"{INPUT_DIR}/python_nodes.dyn"))
|
||||
self.assertEqual(the_file.basename, "python_nodes")
|
||||
self.assertEqual(the_file.dirpath, pathlib.Path(INPUT_DIR))
|
||||
self.assertEqual(the_file.realpath, pathlib.Path(path).resolve())
|
||||
|
||||
self.assertEqual(the_file.mtime, 1678287111.4672492)
|
||||
self.assertEqual(the_file.mtimeiso, "2023-03-08T15:51:51.467249")
|
||||
self.assertTrue(the_file.exists)
|
||||
self.assertEqual(the_file.extension, ".dyn")
|
||||
self.assertFalse(the_file.modified)
|
||||
|
||||
def test_init_newfile(self):
|
||||
paths = [
|
||||
f"{INPUT_DIR}/new_file.dyn",
|
||||
pathlib.Path(f"{INPUT_DIR}/new_file.dyn")
|
||||
]
|
||||
|
||||
if platform.system() == "Windows":
|
||||
paths.extend([
|
||||
fr"{INPUT_DIR}\new_file.dyn",
|
||||
pathlib.Path(fr"{INPUT_DIR}\new_file.dyn")
|
||||
])
|
||||
|
||||
for path in paths:
|
||||
the_file = dyn2py.File(path)
|
||||
|
||||
self.assertEqual(the_file.filepath,
|
||||
pathlib.Path(f"{INPUT_DIR}/new_file.dyn"))
|
||||
self.assertEqual(the_file.basename, "new_file")
|
||||
self.assertEqual(the_file.dirpath, pathlib.Path(INPUT_DIR))
|
||||
self.assertEqual(the_file.realpath, pathlib.Path(path).resolve())
|
||||
|
||||
self.assertEqual(the_file.mtime, 0.0)
|
||||
self.assertEqual(the_file.mtimeiso, "")
|
||||
self.assertFalse(the_file.exists)
|
||||
self.assertEqual(the_file.extension, ".dyn")
|
||||
self.assertFalse(the_file.modified)
|
||||
|
||||
def test_newer(self):
|
||||
older_file = dyn2py.File(f"{INPUT_DIR}/python_nodes.dyn")
|
||||
newer_file = dyn2py.File(f"{INPUT_DIR}/no_python.dyn")
|
||||
nonexisting_file = dyn2py.File(f"{INPUT_DIR}/new_file.dyn")
|
||||
|
||||
self.assertTrue(newer_file.is_newer(older_file))
|
||||
self.assertTrue(newer_file.is_newer(nonexisting_file))
|
||||
|
||||
self.assertFalse(older_file.is_newer(newer_file))
|
||||
self.assertTrue(older_file.is_newer(nonexisting_file))
|
||||
|
||||
self.assertFalse(nonexisting_file.is_newer(older_file))
|
||||
self.assertFalse(nonexisting_file.is_newer(newer_file))
|
||||
|
||||
def test_write(self):
|
||||
existing_file = dyn2py.File(f"{INPUT_DIR}/python_nodes.dyn")
|
||||
nonexisting_file = dyn2py.File(f"{INPUT_DIR}/new_file.dyn")
|
||||
options = dyn2py.Options()
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
existing_file.write(options)
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
nonexisting_file.write(options)
|
||||
19
tests/test_PythonFile.py
Normal file
19
tests/test_PythonFile.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import unittest
|
||||
|
||||
from tests.support import *
|
||||
|
||||
class TestPythonFile(unittest.TestCase):
|
||||
pass
|
||||
|
||||
# Missing variables:
|
||||
# code
|
||||
# header_data
|
||||
# text
|
||||
# open_files
|
||||
|
||||
# Missing methods:
|
||||
# generate_text()
|
||||
# update_dynamo()
|
||||
# get_source_dynamo_file()
|
||||
# read()
|
||||
# write()
|
||||
63
tests/test_PythonNode.py
Normal file
63
tests/test_PythonNode.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import unittest
|
||||
import dyn2py
|
||||
import hashlib
|
||||
from tests.support import *
|
||||
|
||||
|
||||
class TestPythonNode(unittest.TestCase):
|
||||
|
||||
def test_init_from_dyn(self):
|
||||
dyn = dyn2py.DynamoFile(f"{INPUT_DIR}/single_node.dyn")
|
||||
dyn.read()
|
||||
node_dict = next((n for n in dyn.full_dict["Nodes"]
|
||||
if n["NodeType"] == "PythonScriptNode"), {})
|
||||
|
||||
# Found a node:
|
||||
self.assertTrue(node_dict)
|
||||
|
||||
node_views = dyn.full_dict["View"]["NodeViews"]
|
||||
|
||||
node = dyn2py.PythonNode(
|
||||
node_dict_from_dyn=node_dict,
|
||||
full_nodeviews_dict_from_dyn=node_views,
|
||||
source_dynamo_file=dyn
|
||||
)
|
||||
|
||||
self.assertEqual(node.id, "1c5d99792882409e97e132b3e9f814b0")
|
||||
self.assertEqual(node.engine, "CPython3")
|
||||
self.assertEqual(node.checksum, "ec2c85a11ddbf8375da03f11272d427a")
|
||||
self.assertEqual(node.name, "Python Script")
|
||||
self.assertEqual(
|
||||
node.filename, "single_node_1c5d99792882409e97e132b3e9f814b0.py")
|
||||
|
||||
def test_init_from_py(self):
|
||||
|
||||
cleanup_output_dir()
|
||||
|
||||
# Extract py:
|
||||
options = dyn2py.Options(python_folder=OUTPUT_DIR)
|
||||
dyn = dyn2py.DynamoFile(f"{INPUT_DIR}/single_node.dyn")
|
||||
dyn.extract_python(options)
|
||||
|
||||
# Open the extracted file and replace a string:
|
||||
with open(f"{OUTPUT_DIR}/single_node_1c5d99792882409e97e132b3e9f814b0.py") as orig_py, \
|
||||
open(f"{OUTPUT_DIR}/single_node_mod.py", "w") as mod_py:
|
||||
for line in orig_py:
|
||||
if "asd_string" in line:
|
||||
line = line.replace("asd_string", "qwe_string")
|
||||
mod_py.write(line)
|
||||
|
||||
py = dyn2py.PythonFile(f"{OUTPUT_DIR}/single_node_mod.py")
|
||||
py.read()
|
||||
|
||||
node = dyn2py.PythonNode(
|
||||
node_id=py.header_data["py_id"],
|
||||
engine=py.header_data["py_engine"],
|
||||
code=py.code,
|
||||
checksum=hashlib.md5(py.code.encode()).hexdigest()
|
||||
)
|
||||
|
||||
self.assertEqual(node.id, "1c5d99792882409e97e132b3e9f814b0")
|
||||
self.assertEqual(node.engine, "CPython3")
|
||||
self.assertEqual(node.checksum, "bf0f039ef6f11c3043e0821143801d48")
|
||||
|
||||
Reference in New Issue
Block a user