Files
IfcOpenShell/src/ifcedit/tests/test_main.py
T
Andrej730 9d78df392d black .
2026-04-01 10:37:07 +05:00

212 lines
6.7 KiB
Python

# This file was generated with the assistance of an AI coding tool.
import json
import subprocess
import sys
import ifcopenshell
import pytest
def run_ifcedit(*args, stdin=None):
"""Run ifcedit as a subprocess and return (stdout, stderr, returncode)."""
result = subprocess.run(
[sys.executable, "-m", "ifcedit", *args],
capture_output=True,
text=True,
input=stdin,
)
return result.stdout, result.stderr, result.returncode
class TestListCommand:
def test_list_all_modules(self):
stdout, stderr, rc = run_ifcedit("list")
assert rc == 0
data = json.loads(stdout)
assert isinstance(data, list)
module_names = [m["module"] for m in data]
assert "root" in module_names
assert "spatial" in module_names
def test_list_module_functions(self):
stdout, stderr, rc = run_ifcedit("list", "root")
assert rc == 0
data = json.loads(stdout)
assert isinstance(data, list)
names = [f["name"] for f in data]
assert "create_entity" in names
def test_list_text_format(self):
stdout, stderr, rc = run_ifcedit("--format", "text", "list")
assert rc == 0
assert "root" in stdout
class TestDocsCommand:
def test_docs_create_entity(self):
stdout, stderr, rc = run_ifcedit("docs", "root.create_entity")
assert rc == 0
data = json.loads(stdout)
assert data["module"] == "root"
assert data["function"] == "create_entity"
assert "params" in data
def test_docs_invalid_path(self):
stdout, stderr, rc = run_ifcedit("docs", "invalid_path")
assert rc != 0
assert "module.function" in stderr
def test_docs_unknown_function(self):
stdout, stderr, rc = run_ifcedit("docs", "root.nonexistent")
assert rc != 0
class TestRunCommand:
def test_create_entity(self, model_file):
stdout, stderr, rc = run_ifcedit(
"run", model_file, "root.create_entity", "--ifc_class", "IfcWall", "--name", "CLIWall"
)
assert rc == 0, f"stderr: {stderr}"
data = json.loads(stdout)
assert data["ok"] is True
assert data["result"]["type"] == "IfcWall"
assert data["result"]["name"] == "CLIWall"
def test_dry_run(self, model_file):
stdout, stderr, rc = run_ifcedit("run", model_file, "root.create_entity", "--dry-run", "--ifc_class", "IfcWall")
assert rc == 0
data = json.loads(stdout)
assert data["ok"] is True
assert data["dry_run"] is True
def test_output_to_different_file(self, model_file, tmp_path):
output = str(tmp_path / "output.ifc")
stdout, stderr, rc = run_ifcedit(
"run", model_file, "root.create_entity", "-o", output, "--ifc_class", "IfcSlab"
)
assert rc == 0, f"stderr: {stderr}"
data = json.loads(stdout)
assert data["ok"] is True
import os
assert os.path.exists(output)
def test_run_error_bad_function(self, model_file):
stdout, stderr, rc = run_ifcedit("run", model_file, "root.nonexistent")
assert rc != 0
def test_run_invalid_function_path(self, model_file):
stdout, stderr, rc = run_ifcedit("run", model_file, "invalid_path")
assert rc != 0
assert "module.function" in stderr
class TestForeachCommand:
def _select_json(self, model, ifc_class):
"""Build a JSON array like ifcquery select would produce."""
elements = model.by_type(ifc_class)
return json.dumps([{"id": e.id(), "type": e.is_a(), "name": getattr(e, "Name", None)} for e in elements])
def test_foreach_rename(self, model, model_file):
walls_json = self._select_json(model, "IfcWall")
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"attribute.edit_attributes",
"--product",
"{id}",
"--attributes",
'{"Name": "Renamed"}',
stdin=walls_json,
)
assert rc == 0, f"stderr: {stderr}"
data = json.loads(stdout)
assert data["ok"] is True
assert data["count"] == 1
assert data["errors"] == []
updated = ifcopenshell.open(model_file)
assert updated.by_type("IfcWall")[0].Name == "Renamed"
def test_foreach_multiple_elements(self, model, model_file):
# Build a two-item list by selecting all IfcObject (includes spatial structure + elements)
elements_json = self._select_json(model, "IfcObject")
items = json.loads(elements_json)
assert len(items) >= 2
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"attribute.edit_attributes",
"--product",
"{id}",
"--attributes",
'{"Name": "Bulk"}',
stdin=elements_json,
)
assert rc == 0, f"stderr: {stderr}"
data = json.loads(stdout)
assert data["ok"] is True
assert data["count"] == len(items)
def test_foreach_empty_list(self, model_file):
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"attribute.edit_attributes",
"--product",
"{id}",
"--attributes",
'{"Name": "X"}',
stdin="[]",
)
assert rc == 0
data = json.loads(stdout)
assert data["ok"] is True
assert data["count"] == 0
def test_foreach_invalid_json_stdin(self, model_file):
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"root.remove_product",
"--product",
"{id}",
stdin="not json",
)
assert rc != 0
assert "Error" in stderr
def test_foreach_not_array_stdin(self, model_file):
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"root.remove_product",
"--product",
"{id}",
stdin='{"id": 1}',
)
assert rc != 0
assert "Error" in stderr
def test_foreach_output_to_different_file(self, model, model_file, tmp_path):
import os
output = str(tmp_path / "out.ifc")
walls_json = self._select_json(model, "IfcWall")
stdout, stderr, rc = run_ifcedit(
"foreach",
model_file,
"attribute.edit_attributes",
"-o",
output,
"--product",
"{id}",
"--attributes",
'{"Name": "OutFile"}',
stdin=walls_json,
)
assert rc == 0, f"stderr: {stderr}"
assert os.path.exists(output)
updated = ifcopenshell.open(output)
assert updated.by_type("IfcWall")[0].Name == "OutFile"