Last active
May 26, 2023 13:35
-
-
Save unwave/55fa7d4c551d93840db920506bd2666a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test blender socket custom properties | |
def get_script(func, *args, **kwargs): | |
import textwrap | |
import inspect | |
import json | |
return '\n'.join([ | |
textwrap.dedent(inspect.getsource(func)), | |
"import json", | |
f"{func.__name__}(*json.loads(r'{json.dumps(args)}'), **json.loads(r'{json.dumps(kwargs)}'))" | |
]) | |
def ensure_site_packages(packages: list, directory: str): | |
""" | |
`packages`: list of tuples (<import name>, <pip name>) | |
`directory`: a folder for site packages, will be created if does not exist and added to `sys.path` | |
""" | |
if not packages: | |
return | |
import bpy | |
import os | |
import sys | |
import importlib | |
import importlib.util | |
os.makedirs(directory, exist_ok = True) | |
if not directory in sys.path: | |
sys.path.append(directory) | |
modules_to_install = [module[1] for module in packages if not importlib.util.find_spec(module[0])] | |
if not modules_to_install: | |
return | |
if modules_to_install: | |
result = input(f'Install {modules_to_install} to: {directory}? Y/N:') | |
if not result.lower() == 'y': | |
quit() | |
if bpy.app.version < (2,91,0): | |
python_binary = bpy.app.binary_path_python | |
else: | |
python_binary = sys.executable | |
import subprocess | |
subprocess.run([python_binary, '-m', 'ensurepip'], check=True) | |
subprocess.run([python_binary, '-m', 'pip', 'install', *modules_to_install, "--target", directory], check=True) | |
importlib.invalidate_caches() | |
def is_in_blender(): | |
try: | |
import bpy | |
return bool(bpy.app.version) and bool(bpy.app.binary_path) | |
except: | |
return False | |
def get_mat(): | |
import bpy | |
material = bpy.data.materials.new('test_mat') | |
material.use_nodes = True | |
material.use_fake_user = True | |
material.node_tree.nodes.clear() | |
return material | |
def pytest_namespace(): | |
return { | |
'mat_name': '', | |
'blend_file': '', | |
'rand_value_1': None, | |
'rand_value_2': None | |
} | |
def test_create(): | |
import pytest | |
import bpy | |
import os | |
import random | |
material = get_mat() | |
pytest.mat_name = material.name | |
nodes = material.node_tree.nodes | |
math = nodes.new('ShaderNodeMath') | |
math2 = nodes.new('ShaderNodeMath') | |
input_0 = math.inputs[0] | |
input_1 = math2.inputs[1] | |
input_0['my_default_value'] = int(random.random() * 1000) | |
input_1['my_default_value'] = int(random.random() * 1000) | |
math2.inputs[1]['will_be_deleted'] = 'some_value' | |
pytest.rand_value_1 = input_0['my_default_value'] | |
pytest.rand_value_2 = input_1['my_default_value'] | |
pytest.blend_file = os.path.join(bpy.app.tempdir, f'test_blend{random.random()}.blend') | |
bpy.ops.wm.save_mainfile(filepath=pytest.blend_file) | |
def test_check(): | |
import pytest | |
import bpy | |
if bpy.app.version > (2,90,0): | |
bpy.ops.wm.read_homefile(load_ui=True, use_factory_startup=True, use_empty = True) | |
else: | |
bpy.ops.wm.read_homefile(load_ui=True, use_empty = True) | |
bpy.ops.wm.open_mainfile(filepath=pytest.blend_file) | |
material = bpy.data.materials[pytest.mat_name] | |
nodes = material.node_tree.nodes | |
print(dict(nodes[0].inputs[0].items())) | |
assert nodes[0].inputs[0]['my_default_value'] == pytest.rand_value_1 | |
print(dict(nodes[1].inputs[1].items())) | |
assert nodes[1].inputs[1]['my_default_value'] == pytest.rand_value_2 | |
try: | |
nodes[1].inputs[1].id_properties_clear() | |
except AttributeError: | |
assert nodes[1].inputs[1]['will_be_deleted'] | |
del nodes[1].inputs[1]['will_be_deleted'] | |
finally: | |
with pytest.raises(KeyError): | |
nodes[1].inputs[1]['will_be_deleted'] | |
def test_separate_instance(): | |
import subprocess | |
import pytest | |
import bpy | |
def run(value): | |
import bpy | |
assert bpy.data.materials['test_mat'].node_tree.nodes[0].inputs[0]['my_default_value'] == value | |
subprocess.run([bpy.app.binary_path, '--python-exit-code', '1', '-b', '-noaudio', '--factory-startup', pytest.blend_file, '--python-expr', get_script(run, pytest.rand_value_1)], check=True) | |
if __name__ == "__main__" and is_in_blender(): | |
import site | |
ensure_site_packages([("pytest", "pytest")], directory = site.getusersitepackages()) | |
import pytest | |
raise SystemExit(pytest.main([ | |
'-svv', | |
__file__ | |
])) | |
blenders = [ | |
r'blender', | |
r'C:\blender\blender-3.1.2-windows-x64\blender.exe', | |
r'C:\blender\blender-3.6.0-alpha+main.e078419c9c12-windows.amd64-release\blender.exe', | |
r'C:\Program Files (x86)\Steam\steamapps\common\Blender\blender.exe', | |
r'D:\games\SteamLibrary\steamapps\common\blender_293\blender.exe', | |
r'D:\games\SteamLibrary\steamapps\common\blender-2.83.13-windows64\blender.exe', | |
r'D:\source\software\blender\blender-2.82-windows64\blender.exe', | |
r'D:\games\SteamLibrary\steamapps\common\blender-2.79.0-git.e045fe53f1b0-windows64\blender.exe', | |
] | |
if __name__ == '__main__' and not is_in_blender(): | |
import subprocess | |
import os | |
for blender in blenders: | |
print('\n') | |
print('#' * os.get_terminal_size()[0]) | |
# print(subprocess.check_output([blender, '--version']).splitlines()[0].decode()) | |
subprocess.run([blender, '--python-exit-code', '1', '-b', '-noaudio', '--factory-startup', '--python', __file__]) | |
if os.name == 'nt': | |
os.system('pause') | |
else: | |
input('Press Enter to exit...') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment