From d9078fcc76f7426569d7fd8e699e245b61cf443c Mon Sep 17 00:00:00 2001 From: Elmom Date: Mon, 26 Jul 2010 20:56:02 +0300 Subject: [PATCH] Added testing infra using py.test. Catches parse errors already, but stl compiling tests fail --- involute_gears.scad | 12 ++++++++++-- materials.scad | 1 + openscad_utils.py | 27 +++++++++++++++++++++++--- screw.scad | 15 ++++++++++----- test_compile.py | 46 +++++++++++++++++++++++++++++++++++++-------- 5 files changed, 83 insertions(+), 18 deletions(-) diff --git a/involute_gears.scad b/involute_gears.scad index 2756628..1264903 100644 --- a/involute_gears.scad +++ b/involute_gears.scad @@ -14,13 +14,21 @@ //test_gears (); // Meshing Double Helix: -//meshing_double_helix (); +//test_meshing_double_helix (); + +module test_meshing_double_helix(){ + test_meshing_double_helix (); +} // Demonstrate the backlash option for Spur gears. //test_backlash (); // Demonstrate how to make meshing bevel gears. -bevel_gear_pair (); +//test_bevel_gear_pair(); + +module test_bevel_gear_pair(){ + bevel_gear_pair (); +} pi=3.1415926535897932384626433832795; diff --git a/materials.scad b/materials.scad index 520495b..f75edf7 100644 --- a/materials.scad +++ b/materials.scad @@ -16,6 +16,7 @@ Steel = [0.65, 0.67, 0.72]; Stainless = [0.45, 0.43, 0.5]; Aluminum = [0.77, 0.77, 0.8]; Brass = [0.88, 0.78, 0.5]; +Transparent = [1, 1, 1, 0.2]; // Example, uncomment to view //color_demo(); diff --git a/openscad_utils.py b/openscad_utils.py index 60c6919..51f383a 100644 --- a/openscad_utils.py +++ b/openscad_utils.py @@ -1,17 +1,16 @@ -import py, re +import py, re, os, signal, time +from subprocess import Popen, PIPE mod_re = (r"\bmodule\s+(", r")\s*\(\s*") func_re = (r"\bfunction\s+(", r")\s*\(") def extract_mod_names(fpath, name_re=r"\w+"): regex = name_re.join(mod_re) - print regex matcher = re.compile(regex) return (m.group(1) for m in matcher.finditer(fpath.read())) def extract_func_names(fpath, name_re=r"\w+"): regex = name_re.join(func_re) - print regex matcher = re.compile(regex) return (m.group(1) for m in matcher.finditer(fpath.read())) @@ -28,3 +27,25 @@ def collect_test_modules(): return test_files collect_test_modules() + +def call_openscad(path, stlpath, timeout=20): + try: + proc = Popen(['openscad', '-s', str(stlpath), str(path)], + stdout=PIPE, stderr=PIPE, close_fds=True) + calltime = time.time() + #print calltime + while True: + if proc.poll() is not None: + break + time.sleep(0.1) + #print time.time() + if time.time() > calltime + timeout: + raise Exception("Timeout") + finally: + try: + proc.terminate() + proc.kill() + except OSError: + pass + + return (proc.returncode,) + proc.communicate() diff --git a/screw.scad b/screw.scad index 3a9d4c5..e8598af 100644 --- a/screw.scad +++ b/screw.scad @@ -11,6 +11,11 @@ outside_diameter inner_diameter: thickness of the shaft */ +//Uncomment to see examples +//test_auger(); +//test_ball_groove(); +//test_ball_groove2(); +//test_ball_screw(); module helix(pitch, length, slices=500){ rotations = length/pitch; @@ -26,7 +31,7 @@ module auger(pitch, length, outside_diameter, inner_diameter) { } } -translate([300, 0, 0]) auger(100, 300); +module test_auger(){translate([300, 0, 0]) auger(100, 300);} module ball_groove(pitch, length, diameter, ball_radius=10) { @@ -35,8 +40,7 @@ module ball_groove(pitch, length, diameter, ball_radius=10) { circle(r = ball_radius); } -translate([0, 300, 0]) ball_groove(100, 300, 10); - +module test_ball_groove(){ translate([0, 300, 0]) ball_groove(100, 300, 10);} module ball_groove2(pitch, length, diameter, ball_radius, slices=200){ rotations = length/pitch; @@ -51,9 +55,10 @@ module ball_groove2(pitch, length, diameter, ball_radius, slices=200){ } } -translate([0, 0, 0]) ball_groove2(100, 300, 100, 10); - +module test_ball_groove2(){translate([0, 0, 0]) ball_groove2(100, 300, 100, 10);} module ball_screw(pitch, length, bearing_radius=2) { } + +module test_ball_screw(){} diff --git a/test_compile.py b/test_compile.py index c738f38..2208186 100644 --- a/test_compile.py +++ b/test_compile.py @@ -1,14 +1,44 @@ +import py + from openscad_utils import * def pytest_generate_tests(metafunc): - if "mod_name" in metafunc.funcargnames: - for fpath, mod_names in collect_test_modules().items(): - for mod_name in mod_names: - metafunc.addcall(funcargs=dict(mod_name=mod_name, mod_file=fpath)) + if "modpath" in metafunc.funcargnames: + if "modname" in metafunc.funcargnames: + for fpath, modnames in collect_test_modules().items(): + for modname in modnames: + metafunc.addcall(funcargs=dict(modname=modname, modpath=fpath)) + else: + dirpath = py.path.local("./") + for fpath in dirpath.visit('*.scad'): + metafunc.addcall(funcargs=dict(modpath=fpath)) temppath = py.test.ensuretemp('MCAD') -def test_func(mod_name, mod_file, capfd): - fpath = temppath.join(mod_file.base_name) - - call_openscad(path=fpath) +def test_compile(modname, modpath): + tempname = "test_" + modpath.basename + modname + fpath = temppath.join(tempname) + stlpath = temppath.join(tempname + ".stl") + f = fpath.open('w') + f.write(""" +//generated testfile +include <%s> + +%s() +""" % (modpath, modname)) + f.flush + output = call_openscad(path=fpath, stlpath=stlpath) + print output + assert output[0] is 0 + assert "warning" or "error" not in output[2].strip().lowercase() + assert len(stlpath.readlines()) > 2 + +def test_compile_default(modpath): + tempname = "test_" + modpath.basename + stlpath = temppath.join(tempname + ".stl") + output = call_openscad(path=modpath, stlpath=stlpath) + print output + assert output[0] is 0 + assert "warning" or "error" not in output[2].strip().lowercase() + +