Migrate to pytest (#111)
* Migrate to pytest All tests were update to use pytest. Tests were alse black formatted. Eventually all code will be black formatted but need to merge some PRs first.
This commit is contained in:
parent
404384cf91
commit
ef589a0640
20 changed files with 2349 additions and 2097 deletions
|
|
@ -1,4 +0,0 @@
|
|||
[report]
|
||||
omit =
|
||||
*/python?.?/*
|
||||
*/site-packages/nose/*
|
||||
2
.github/workflows/pcb-tools.yml
vendored
2
.github/workflows/pcb-tools.yml
vendored
|
|
@ -18,9 +18,7 @@ jobs:
|
|||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements-dev.txt
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pip install pytest
|
||||
pytest
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -48,3 +48,4 @@ Thumbs.db
|
|||
|
||||
# Virtual environment
|
||||
venv
|
||||
coverage.xml
|
||||
|
|
|
|||
10
Makefile
10
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
PYTHON ?= python
|
||||
NOSETESTS ?= nosetests
|
||||
PYTEST ?= pytest
|
||||
|
||||
DOC_ROOT = doc
|
||||
EXAMPLES = examples
|
||||
|
|
@ -8,17 +8,17 @@ EXAMPLES = examples
|
|||
.PHONY: clean
|
||||
clean: doc-clean
|
||||
find . -name '*.pyc' -delete
|
||||
rm -rf coverage .coverage
|
||||
rm -rf *.egg-info
|
||||
rm -f coverage.xml
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(NOSETESTS) -s -v gerber
|
||||
$(PYTEST)
|
||||
|
||||
.PHONY: test-coverage
|
||||
test-coverage:
|
||||
rm -rf coverage .coverage
|
||||
$(NOSETESTS) -s -v --with-coverage --cover-package=gerber
|
||||
rm -rf coverage.xml
|
||||
$(PYTEST) --cov=./ --cov-report=xml
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
|
|
|
|||
|
|
@ -55,6 +55,6 @@ Dependencies for developing and testing pcb-tools are listed in requirements-dev
|
|||
(venv)$ pip install -r requirements-dev.txt
|
||||
(venv)$ pip install -e .
|
||||
|
||||
We use nose to run pcb-tools's suite of unittests and doctests.
|
||||
We use [pytest](https://docs.pytest.org/en/latest/) to run pcb-tools's suite of unittests and doctests.
|
||||
|
||||
(venv)$ nosetests
|
||||
(venv)$ pytest
|
||||
|
|
|
|||
|
|
@ -3,385 +3,393 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
from .tests import *
|
||||
import pytest
|
||||
|
||||
from ..am_statements import *
|
||||
from ..am_statements import inch, metric
|
||||
|
||||
|
||||
def test_AMPrimitive_ctor():
|
||||
for exposure in ('on', 'off', 'ON', 'OFF'):
|
||||
for exposure in ("on", "off", "ON", "OFF"):
|
||||
for code in (0, 1, 2, 4, 5, 6, 7, 20, 21, 22):
|
||||
p = AMPrimitive(code, exposure)
|
||||
assert_equal(p.code, code)
|
||||
assert_equal(p.exposure, exposure.lower())
|
||||
assert p.code == code
|
||||
assert p.exposure == exposure.lower()
|
||||
|
||||
|
||||
def test_AMPrimitive_validation():
|
||||
assert_raises(TypeError, AMPrimitive, '1', 'off')
|
||||
assert_raises(ValueError, AMPrimitive, 0, 'exposed')
|
||||
assert_raises(ValueError, AMPrimitive, 3, 'off')
|
||||
pytest.raises(TypeError, AMPrimitive, "1", "off")
|
||||
pytest.raises(ValueError, AMPrimitive, 0, "exposed")
|
||||
pytest.raises(ValueError, AMPrimitive, 3, "off")
|
||||
|
||||
|
||||
def test_AMPrimitive_conversion():
|
||||
p = AMPrimitive(4, 'on')
|
||||
assert_raises(NotImplementedError, p.to_inch)
|
||||
assert_raises(NotImplementedError, p.to_metric)
|
||||
p = AMPrimitive(4, "on")
|
||||
pytest.raises(NotImplementedError, p.to_inch)
|
||||
pytest.raises(NotImplementedError, p.to_metric)
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_ctor():
|
||||
c = AMCommentPrimitive(0, ' This is a comment *')
|
||||
assert_equal(c.code, 0)
|
||||
assert_equal(c.comment, 'This is a comment')
|
||||
c = AMCommentPrimitive(0, " This is a comment *")
|
||||
assert c.code == 0
|
||||
assert c.comment == "This is a comment"
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_validation():
|
||||
assert_raises(ValueError, AMCommentPrimitive, 1, 'This is a comment')
|
||||
pytest.raises(ValueError, AMCommentPrimitive, 1, "This is a comment")
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_factory():
|
||||
c = AMCommentPrimitive.from_gerber('0 Rectangle with rounded corners. *')
|
||||
assert_equal(c.code, 0)
|
||||
assert_equal(c.comment, 'Rectangle with rounded corners.')
|
||||
c = AMCommentPrimitive.from_gerber("0 Rectangle with rounded corners. *")
|
||||
assert c.code == 0
|
||||
assert c.comment == "Rectangle with rounded corners."
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_dump():
|
||||
c = AMCommentPrimitive(0, 'Rectangle with rounded corners.')
|
||||
assert_equal(c.to_gerber(), '0 Rectangle with rounded corners. *')
|
||||
c = AMCommentPrimitive(0, "Rectangle with rounded corners.")
|
||||
assert c.to_gerber() == "0 Rectangle with rounded corners. *"
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_conversion():
|
||||
c = AMCommentPrimitive(0, 'Rectangle with rounded corners.')
|
||||
c = AMCommentPrimitive(0, "Rectangle with rounded corners.")
|
||||
ci = c
|
||||
cm = c
|
||||
ci.to_inch()
|
||||
cm.to_metric()
|
||||
assert_equal(c, ci)
|
||||
assert_equal(c, cm)
|
||||
assert c == ci
|
||||
assert c == cm
|
||||
|
||||
|
||||
def test_AMCommentPrimitive_string():
|
||||
c = AMCommentPrimitive(0, 'Test Comment')
|
||||
assert_equal(str(c), '<Aperture Macro Comment: Test Comment>')
|
||||
c = AMCommentPrimitive(0, "Test Comment")
|
||||
assert str(c) == "<Aperture Macro Comment: Test Comment>"
|
||||
|
||||
|
||||
def test_AMCirclePrimitive_ctor():
|
||||
test_cases = ((1, 'on', 0, (0, 0)),
|
||||
(1, 'off', 1, (0, 1)),
|
||||
(1, 'on', 2.5, (0, 2)),
|
||||
(1, 'off', 5.0, (3, 3)))
|
||||
test_cases = (
|
||||
(1, "on", 0, (0, 0)),
|
||||
(1, "off", 1, (0, 1)),
|
||||
(1, "on", 2.5, (0, 2)),
|
||||
(1, "off", 5.0, (3, 3)),
|
||||
)
|
||||
for code, exposure, diameter, position in test_cases:
|
||||
c = AMCirclePrimitive(code, exposure, diameter, position)
|
||||
assert_equal(c.code, code)
|
||||
assert_equal(c.exposure, exposure)
|
||||
assert_equal(c.diameter, diameter)
|
||||
assert_equal(c.position, position)
|
||||
assert c.code == code
|
||||
assert c.exposure == exposure
|
||||
assert c.diameter == diameter
|
||||
assert c.position == position
|
||||
|
||||
|
||||
def test_AMCirclePrimitive_validation():
|
||||
assert_raises(ValueError, AMCirclePrimitive, 2, 'on', 0, (0, 0))
|
||||
pytest.raises(ValueError, AMCirclePrimitive, 2, "on", 0, (0, 0))
|
||||
|
||||
|
||||
def test_AMCirclePrimitive_factory():
|
||||
c = AMCirclePrimitive.from_gerber('1,0,5,0,0*')
|
||||
assert_equal(c.code, 1)
|
||||
assert_equal(c.exposure, 'off')
|
||||
assert_equal(c.diameter, 5)
|
||||
assert_equal(c.position, (0, 0))
|
||||
c = AMCirclePrimitive.from_gerber("1,0,5,0,0*")
|
||||
assert c.code == 1
|
||||
assert c.exposure == "off"
|
||||
assert c.diameter == 5
|
||||
assert c.position == (0, 0)
|
||||
|
||||
|
||||
def test_AMCirclePrimitive_dump():
|
||||
c = AMCirclePrimitive(1, 'off', 5, (0, 0))
|
||||
assert_equal(c.to_gerber(), '1,0,5,0,0*')
|
||||
c = AMCirclePrimitive(1, 'on', 5, (0, 0))
|
||||
assert_equal(c.to_gerber(), '1,1,5,0,0*')
|
||||
c = AMCirclePrimitive(1, "off", 5, (0, 0))
|
||||
assert c.to_gerber() == "1,0,5,0,0*"
|
||||
c = AMCirclePrimitive(1, "on", 5, (0, 0))
|
||||
assert c.to_gerber() == "1,1,5,0,0*"
|
||||
|
||||
|
||||
def test_AMCirclePrimitive_conversion():
|
||||
c = AMCirclePrimitive(1, 'off', 25.4, (25.4, 0))
|
||||
c = AMCirclePrimitive(1, "off", 25.4, (25.4, 0))
|
||||
c.to_inch()
|
||||
assert_equal(c.diameter, 1)
|
||||
assert_equal(c.position, (1, 0))
|
||||
assert c.diameter == 1
|
||||
assert c.position == (1, 0)
|
||||
|
||||
c = AMCirclePrimitive(1, 'off', 1, (1, 0))
|
||||
c = AMCirclePrimitive(1, "off", 1, (1, 0))
|
||||
c.to_metric()
|
||||
assert_equal(c.diameter, 25.4)
|
||||
assert_equal(c.position, (25.4, 0))
|
||||
assert c.diameter == 25.4
|
||||
assert c.position == (25.4, 0)
|
||||
|
||||
|
||||
def test_AMVectorLinePrimitive_validation():
|
||||
assert_raises(ValueError, AMVectorLinePrimitive,
|
||||
3, 'on', 0.1, (0, 0), (3.3, 5.4), 0)
|
||||
pytest.raises(
|
||||
ValueError, AMVectorLinePrimitive, 3, "on", 0.1, (0, 0), (3.3, 5.4), 0
|
||||
)
|
||||
|
||||
|
||||
def test_AMVectorLinePrimitive_factory():
|
||||
l = AMVectorLinePrimitive.from_gerber('20,1,0.9,0,0.45,12,0.45,0*')
|
||||
assert_equal(l.code, 20)
|
||||
assert_equal(l.exposure, 'on')
|
||||
assert_equal(l.width, 0.9)
|
||||
assert_equal(l.start, (0, 0.45))
|
||||
assert_equal(l.end, (12, 0.45))
|
||||
assert_equal(l.rotation, 0)
|
||||
l = AMVectorLinePrimitive.from_gerber("20,1,0.9,0,0.45,12,0.45,0*")
|
||||
assert l.code == 20
|
||||
assert l.exposure == "on"
|
||||
assert l.width == 0.9
|
||||
assert l.start == (0, 0.45)
|
||||
assert l.end == (12, 0.45)
|
||||
assert l.rotation == 0
|
||||
|
||||
|
||||
def test_AMVectorLinePrimitive_dump():
|
||||
l = AMVectorLinePrimitive.from_gerber('20,1,0.9,0,0.45,12,0.45,0*')
|
||||
assert_equal(l.to_gerber(), '20,1,0.9,0.0,0.45,12.0,0.45,0.0*')
|
||||
l = AMVectorLinePrimitive.from_gerber("20,1,0.9,0,0.45,12,0.45,0*")
|
||||
assert l.to_gerber() == "20,1,0.9,0.0,0.45,12.0,0.45,0.0*"
|
||||
|
||||
|
||||
def test_AMVectorLinePrimtive_conversion():
|
||||
l = AMVectorLinePrimitive(20, 'on', 25.4, (0, 0), (25.4, 25.4), 0)
|
||||
l = AMVectorLinePrimitive(20, "on", 25.4, (0, 0), (25.4, 25.4), 0)
|
||||
l.to_inch()
|
||||
assert_equal(l.width, 1)
|
||||
assert_equal(l.start, (0, 0))
|
||||
assert_equal(l.end, (1, 1))
|
||||
assert l.width == 1
|
||||
assert l.start == (0, 0)
|
||||
assert l.end == (1, 1)
|
||||
|
||||
l = AMVectorLinePrimitive(20, 'on', 1, (0, 0), (1, 1), 0)
|
||||
l = AMVectorLinePrimitive(20, "on", 1, (0, 0), (1, 1), 0)
|
||||
l.to_metric()
|
||||
assert_equal(l.width, 25.4)
|
||||
assert_equal(l.start, (0, 0))
|
||||
assert_equal(l.end, (25.4, 25.4))
|
||||
assert l.width == 25.4
|
||||
assert l.start == (0, 0)
|
||||
assert l.end == (25.4, 25.4)
|
||||
|
||||
|
||||
def test_AMOutlinePrimitive_validation():
|
||||
assert_raises(ValueError, AMOutlinePrimitive, 7, 'on',
|
||||
(0, 0), [(3.3, 5.4), (4.0, 5.4), (0, 0)], 0)
|
||||
assert_raises(ValueError, AMOutlinePrimitive, 4, 'on',
|
||||
(0, 0), [(3.3, 5.4), (4.0, 5.4), (0, 1)], 0)
|
||||
pytest.raises(
|
||||
ValueError,
|
||||
AMOutlinePrimitive,
|
||||
7,
|
||||
"on",
|
||||
(0, 0),
|
||||
[(3.3, 5.4), (4.0, 5.4), (0, 0)],
|
||||
0,
|
||||
)
|
||||
pytest.raises(
|
||||
ValueError,
|
||||
AMOutlinePrimitive,
|
||||
4,
|
||||
"on",
|
||||
(0, 0),
|
||||
[(3.3, 5.4), (4.0, 5.4), (0, 1)],
|
||||
0,
|
||||
)
|
||||
|
||||
|
||||
def test_AMOutlinePrimitive_factory():
|
||||
o = AMOutlinePrimitive.from_gerber('4,1,3,0,0,3,3,3,0,0,0,0*')
|
||||
assert_equal(o.code, 4)
|
||||
assert_equal(o.exposure, 'on')
|
||||
assert_equal(o.start_point, (0, 0))
|
||||
assert_equal(o.points, [(3, 3), (3, 0), (0, 0)])
|
||||
assert_equal(o.rotation, 0)
|
||||
o = AMOutlinePrimitive.from_gerber("4,1,3,0,0,3,3,3,0,0,0,0*")
|
||||
assert o.code == 4
|
||||
assert o.exposure == "on"
|
||||
assert o.start_point == (0, 0)
|
||||
assert o.points == [(3, 3), (3, 0), (0, 0)]
|
||||
assert o.rotation == 0
|
||||
|
||||
|
||||
def test_AMOUtlinePrimitive_dump():
|
||||
o = AMOutlinePrimitive(4, 'on', (0, 0), [(3, 3), (3, 0), (0, 0)], 0)
|
||||
o = AMOutlinePrimitive(4, "on", (0, 0), [(3, 3), (3, 0), (0, 0)], 0)
|
||||
# New lines don't matter for Gerber, but we insert them to make it easier to remove
|
||||
# For test purposes we can ignore them
|
||||
assert_equal(o.to_gerber().replace('\n', ''), '4,1,3,0,0,3,3,3,0,0,0,0*')
|
||||
|
||||
|
||||
assert o.to_gerber().replace("\n", "") == "4,1,3,0,0,3,3,3,0,0,0,0*"
|
||||
|
||||
|
||||
def test_AMOutlinePrimitive_conversion():
|
||||
o = AMOutlinePrimitive(
|
||||
4, 'on', (0, 0), [(25.4, 25.4), (25.4, 0), (0, 0)], 0)
|
||||
o = AMOutlinePrimitive(4, "on", (0, 0), [(25.4, 25.4), (25.4, 0), (0, 0)], 0)
|
||||
o.to_inch()
|
||||
assert_equal(o.start_point, (0, 0))
|
||||
assert_equal(o.points, ((1., 1.), (1., 0.), (0., 0.)))
|
||||
assert o.start_point == (0, 0)
|
||||
assert o.points == ((1.0, 1.0), (1.0, 0.0), (0.0, 0.0))
|
||||
|
||||
o = AMOutlinePrimitive(4, 'on', (0, 0), [(1, 1), (1, 0), (0, 0)], 0)
|
||||
o = AMOutlinePrimitive(4, "on", (0, 0), [(1, 1), (1, 0), (0, 0)], 0)
|
||||
o.to_metric()
|
||||
assert_equal(o.start_point, (0, 0))
|
||||
assert_equal(o.points, ((25.4, 25.4), (25.4, 0), (0, 0)))
|
||||
assert o.start_point == (0, 0)
|
||||
assert o.points == ((25.4, 25.4), (25.4, 0), (0, 0))
|
||||
|
||||
|
||||
def test_AMPolygonPrimitive_validation():
|
||||
assert_raises(ValueError, AMPolygonPrimitive, 6, 'on', 3, (3.3, 5.4), 3, 0)
|
||||
assert_raises(ValueError, AMPolygonPrimitive, 5, 'on', 2, (3.3, 5.4), 3, 0)
|
||||
assert_raises(ValueError, AMPolygonPrimitive, 5, 'on', 13, (3.3, 5.4), 3, 0)
|
||||
pytest.raises(ValueError, AMPolygonPrimitive, 6, "on", 3, (3.3, 5.4), 3, 0)
|
||||
pytest.raises(ValueError, AMPolygonPrimitive, 5, "on", 2, (3.3, 5.4), 3, 0)
|
||||
pytest.raises(ValueError, AMPolygonPrimitive, 5, "on", 13, (3.3, 5.4), 3, 0)
|
||||
|
||||
|
||||
def test_AMPolygonPrimitive_factory():
|
||||
p = AMPolygonPrimitive.from_gerber('5,1,3,3.3,5.4,3,0')
|
||||
assert_equal(p.code, 5)
|
||||
assert_equal(p.exposure, 'on')
|
||||
assert_equal(p.vertices, 3)
|
||||
assert_equal(p.position, (3.3, 5.4))
|
||||
assert_equal(p.diameter, 3)
|
||||
assert_equal(p.rotation, 0)
|
||||
p = AMPolygonPrimitive.from_gerber("5,1,3,3.3,5.4,3,0")
|
||||
assert p.code == 5
|
||||
assert p.exposure == "on"
|
||||
assert p.vertices == 3
|
||||
assert p.position == (3.3, 5.4)
|
||||
assert p.diameter == 3
|
||||
assert p.rotation == 0
|
||||
|
||||
|
||||
def test_AMPolygonPrimitive_dump():
|
||||
p = AMPolygonPrimitive(5, 'on', 3, (3.3, 5.4), 3, 0)
|
||||
assert_equal(p.to_gerber(), '5,1,3,3.3,5.4,3,0*')
|
||||
p = AMPolygonPrimitive(5, "on", 3, (3.3, 5.4), 3, 0)
|
||||
assert p.to_gerber() == "5,1,3,3.3,5.4,3,0*"
|
||||
|
||||
|
||||
def test_AMPolygonPrimitive_conversion():
|
||||
p = AMPolygonPrimitive(5, 'off', 3, (25.4, 0), 25.4, 0)
|
||||
p = AMPolygonPrimitive(5, "off", 3, (25.4, 0), 25.4, 0)
|
||||
p.to_inch()
|
||||
assert_equal(p.diameter, 1)
|
||||
assert_equal(p.position, (1, 0))
|
||||
assert p.diameter == 1
|
||||
assert p.position == (1, 0)
|
||||
|
||||
p = AMPolygonPrimitive(5, 'off', 3, (1, 0), 1, 0)
|
||||
p = AMPolygonPrimitive(5, "off", 3, (1, 0), 1, 0)
|
||||
p.to_metric()
|
||||
assert_equal(p.diameter, 25.4)
|
||||
assert_equal(p.position, (25.4, 0))
|
||||
assert p.diameter == 25.4
|
||||
assert p.position == (25.4, 0)
|
||||
|
||||
|
||||
def test_AMMoirePrimitive_validation():
|
||||
assert_raises(ValueError, AMMoirePrimitive, 7,
|
||||
(0, 0), 5.1, 0.2, 0.4, 6, 0.1, 6.1, 0)
|
||||
pytest.raises(
|
||||
ValueError, AMMoirePrimitive, 7, (0, 0), 5.1, 0.2, 0.4, 6, 0.1, 6.1, 0
|
||||
)
|
||||
|
||||
|
||||
def test_AMMoirePrimitive_factory():
|
||||
m = AMMoirePrimitive.from_gerber('6,0,0,5,0.5,0.5,2,0.1,6,0*')
|
||||
assert_equal(m.code, 6)
|
||||
assert_equal(m.position, (0, 0))
|
||||
assert_equal(m.diameter, 5)
|
||||
assert_equal(m.ring_thickness, 0.5)
|
||||
assert_equal(m.gap, 0.5)
|
||||
assert_equal(m.max_rings, 2)
|
||||
assert_equal(m.crosshair_thickness, 0.1)
|
||||
assert_equal(m.crosshair_length, 6)
|
||||
assert_equal(m.rotation, 0)
|
||||
m = AMMoirePrimitive.from_gerber("6,0,0,5,0.5,0.5,2,0.1,6,0*")
|
||||
assert m.code == 6
|
||||
assert m.position == (0, 0)
|
||||
assert m.diameter == 5
|
||||
assert m.ring_thickness == 0.5
|
||||
assert m.gap == 0.5
|
||||
assert m.max_rings == 2
|
||||
assert m.crosshair_thickness == 0.1
|
||||
assert m.crosshair_length == 6
|
||||
assert m.rotation == 0
|
||||
|
||||
|
||||
def test_AMMoirePrimitive_dump():
|
||||
m = AMMoirePrimitive.from_gerber('6,0,0,5,0.5,0.5,2,0.1,6,0*')
|
||||
assert_equal(m.to_gerber(), '6,0,0,5.0,0.5,0.5,2,0.1,6.0,0.0*')
|
||||
m = AMMoirePrimitive.from_gerber("6,0,0,5,0.5,0.5,2,0.1,6,0*")
|
||||
assert m.to_gerber() == "6,0,0,5.0,0.5,0.5,2,0.1,6.0,0.0*"
|
||||
|
||||
|
||||
def test_AMMoirePrimitive_conversion():
|
||||
m = AMMoirePrimitive(6, (25.4, 25.4), 25.4, 25.4, 25.4, 6, 25.4, 25.4, 0)
|
||||
m.to_inch()
|
||||
assert_equal(m.position, (1., 1.))
|
||||
assert_equal(m.diameter, 1.)
|
||||
assert_equal(m.ring_thickness, 1.)
|
||||
assert_equal(m.gap, 1.)
|
||||
assert_equal(m.crosshair_thickness, 1.)
|
||||
assert_equal(m.crosshair_length, 1.)
|
||||
assert m.position == (1.0, 1.0)
|
||||
assert m.diameter == 1.0
|
||||
assert m.ring_thickness == 1.0
|
||||
assert m.gap == 1.0
|
||||
assert m.crosshair_thickness == 1.0
|
||||
assert m.crosshair_length == 1.0
|
||||
|
||||
m = AMMoirePrimitive(6, (1, 1), 1, 1, 1, 6, 1, 1, 0)
|
||||
m.to_metric()
|
||||
assert_equal(m.position, (25.4, 25.4))
|
||||
assert_equal(m.diameter, 25.4)
|
||||
assert_equal(m.ring_thickness, 25.4)
|
||||
assert_equal(m.gap, 25.4)
|
||||
assert_equal(m.crosshair_thickness, 25.4)
|
||||
assert_equal(m.crosshair_length, 25.4)
|
||||
assert m.position == (25.4, 25.4)
|
||||
assert m.diameter == 25.4
|
||||
assert m.ring_thickness == 25.4
|
||||
assert m.gap == 25.4
|
||||
assert m.crosshair_thickness == 25.4
|
||||
assert m.crosshair_length == 25.4
|
||||
|
||||
|
||||
def test_AMThermalPrimitive_validation():
|
||||
assert_raises(ValueError, AMThermalPrimitive, 8, (0.0, 0.0), 7, 5, 0.2, 0.0)
|
||||
assert_raises(TypeError, AMThermalPrimitive, 7, (0.0, '0'), 7, 5, 0.2, 0.0)
|
||||
|
||||
|
||||
pytest.raises(ValueError, AMThermalPrimitive, 8, (0.0, 0.0), 7, 5, 0.2, 0.0)
|
||||
pytest.raises(TypeError, AMThermalPrimitive, 7, (0.0, "0"), 7, 5, 0.2, 0.0)
|
||||
|
||||
|
||||
def test_AMThermalPrimitive_factory():
|
||||
t = AMThermalPrimitive.from_gerber('7,0,0,7,6,0.2,45*')
|
||||
assert_equal(t.code, 7)
|
||||
assert_equal(t.position, (0, 0))
|
||||
assert_equal(t.outer_diameter, 7)
|
||||
assert_equal(t.inner_diameter, 6)
|
||||
assert_equal(t.gap, 0.2)
|
||||
assert_equal(t.rotation, 45)
|
||||
|
||||
|
||||
t = AMThermalPrimitive.from_gerber("7,0,0,7,6,0.2,45*")
|
||||
assert t.code == 7
|
||||
assert t.position == (0, 0)
|
||||
assert t.outer_diameter == 7
|
||||
assert t.inner_diameter == 6
|
||||
assert t.gap == 0.2
|
||||
assert t.rotation == 45
|
||||
|
||||
|
||||
def test_AMThermalPrimitive_dump():
|
||||
t = AMThermalPrimitive.from_gerber('7,0,0,7,6,0.2,30*')
|
||||
assert_equal(t.to_gerber(), '7,0,0,7.0,6.0,0.2,30.0*')
|
||||
|
||||
|
||||
t = AMThermalPrimitive.from_gerber("7,0,0,7,6,0.2,30*")
|
||||
assert t.to_gerber() == "7,0,0,7.0,6.0,0.2,30.0*"
|
||||
|
||||
|
||||
def test_AMThermalPrimitive_conversion():
|
||||
t = AMThermalPrimitive(7, (25.4, 25.4), 25.4, 25.4, 25.4, 0.0)
|
||||
t.to_inch()
|
||||
assert_equal(t.position, (1., 1.))
|
||||
assert_equal(t.outer_diameter, 1.)
|
||||
assert_equal(t.inner_diameter, 1.)
|
||||
assert_equal(t.gap, 1.)
|
||||
assert t.position == (1.0, 1.0)
|
||||
assert t.outer_diameter == 1.0
|
||||
assert t.inner_diameter == 1.0
|
||||
assert t.gap == 1.0
|
||||
|
||||
t = AMThermalPrimitive(7, (1, 1), 1, 1, 1, 0)
|
||||
t.to_metric()
|
||||
assert_equal(t.position, (25.4, 25.4))
|
||||
assert_equal(t.outer_diameter, 25.4)
|
||||
assert_equal(t.inner_diameter, 25.4)
|
||||
assert_equal(t.gap, 25.4)
|
||||
assert t.position == (25.4, 25.4)
|
||||
assert t.outer_diameter == 25.4
|
||||
assert t.inner_diameter == 25.4
|
||||
assert t.gap == 25.4
|
||||
|
||||
|
||||
def test_AMCenterLinePrimitive_validation():
|
||||
assert_raises(ValueError, AMCenterLinePrimitive,
|
||||
22, 1, 0.2, 0.5, (0, 0), 0)
|
||||
pytest.raises(ValueError, AMCenterLinePrimitive, 22, 1, 0.2, 0.5, (0, 0), 0)
|
||||
|
||||
|
||||
def test_AMCenterLinePrimtive_factory():
|
||||
l = AMCenterLinePrimitive.from_gerber('21,1,6.8,1.2,3.4,0.6,0*')
|
||||
assert_equal(l.code, 21)
|
||||
assert_equal(l.exposure, 'on')
|
||||
assert_equal(l.width, 6.8)
|
||||
assert_equal(l.height, 1.2)
|
||||
assert_equal(l.center, (3.4, 0.6))
|
||||
assert_equal(l.rotation, 0)
|
||||
l = AMCenterLinePrimitive.from_gerber("21,1,6.8,1.2,3.4,0.6,0*")
|
||||
assert l.code == 21
|
||||
assert l.exposure == "on"
|
||||
assert l.width == 6.8
|
||||
assert l.height == 1.2
|
||||
assert l.center == (3.4, 0.6)
|
||||
assert l.rotation == 0
|
||||
|
||||
|
||||
def test_AMCenterLinePrimitive_dump():
|
||||
l = AMCenterLinePrimitive.from_gerber('21,1,6.8,1.2,3.4,0.6,0*')
|
||||
assert_equal(l.to_gerber(), '21,1,6.8,1.2,3.4,0.6,0.0*')
|
||||
l = AMCenterLinePrimitive.from_gerber("21,1,6.8,1.2,3.4,0.6,0*")
|
||||
assert l.to_gerber() == "21,1,6.8,1.2,3.4,0.6,0.0*"
|
||||
|
||||
|
||||
def test_AMCenterLinePrimitive_conversion():
|
||||
l = AMCenterLinePrimitive(21, 'on', 25.4, 25.4, (25.4, 25.4), 0)
|
||||
l = AMCenterLinePrimitive(21, "on", 25.4, 25.4, (25.4, 25.4), 0)
|
||||
l.to_inch()
|
||||
assert_equal(l.width, 1.)
|
||||
assert_equal(l.height, 1.)
|
||||
assert_equal(l.center, (1., 1.))
|
||||
assert l.width == 1.0
|
||||
assert l.height == 1.0
|
||||
assert l.center == (1.0, 1.0)
|
||||
|
||||
l = AMCenterLinePrimitive(21, 'on', 1, 1, (1, 1), 0)
|
||||
l = AMCenterLinePrimitive(21, "on", 1, 1, (1, 1), 0)
|
||||
l.to_metric()
|
||||
assert_equal(l.width, 25.4)
|
||||
assert_equal(l.height, 25.4)
|
||||
assert_equal(l.center, (25.4, 25.4))
|
||||
assert l.width == 25.4
|
||||
assert l.height == 25.4
|
||||
assert l.center == (25.4, 25.4)
|
||||
|
||||
|
||||
def test_AMLowerLeftLinePrimitive_validation():
|
||||
assert_raises(ValueError, AMLowerLeftLinePrimitive,
|
||||
23, 1, 0.2, 0.5, (0, 0), 0)
|
||||
pytest.raises(ValueError, AMLowerLeftLinePrimitive, 23, 1, 0.2, 0.5, (0, 0), 0)
|
||||
|
||||
|
||||
def test_AMLowerLeftLinePrimtive_factory():
|
||||
l = AMLowerLeftLinePrimitive.from_gerber('22,1,6.8,1.2,3.4,0.6,0*')
|
||||
assert_equal(l.code, 22)
|
||||
assert_equal(l.exposure, 'on')
|
||||
assert_equal(l.width, 6.8)
|
||||
assert_equal(l.height, 1.2)
|
||||
assert_equal(l.lower_left, (3.4, 0.6))
|
||||
assert_equal(l.rotation, 0)
|
||||
l = AMLowerLeftLinePrimitive.from_gerber("22,1,6.8,1.2,3.4,0.6,0*")
|
||||
assert l.code == 22
|
||||
assert l.exposure == "on"
|
||||
assert l.width == 6.8
|
||||
assert l.height == 1.2
|
||||
assert l.lower_left == (3.4, 0.6)
|
||||
assert l.rotation == 0
|
||||
|
||||
|
||||
def test_AMLowerLeftLinePrimitive_dump():
|
||||
l = AMLowerLeftLinePrimitive.from_gerber('22,1,6.8,1.2,3.4,0.6,0*')
|
||||
assert_equal(l.to_gerber(), '22,1,6.8,1.2,3.4,0.6,0.0*')
|
||||
l = AMLowerLeftLinePrimitive.from_gerber("22,1,6.8,1.2,3.4,0.6,0*")
|
||||
assert l.to_gerber() == "22,1,6.8,1.2,3.4,0.6,0.0*"
|
||||
|
||||
|
||||
def test_AMLowerLeftLinePrimitive_conversion():
|
||||
l = AMLowerLeftLinePrimitive(22, 'on', 25.4, 25.4, (25.4, 25.4), 0)
|
||||
l = AMLowerLeftLinePrimitive(22, "on", 25.4, 25.4, (25.4, 25.4), 0)
|
||||
l.to_inch()
|
||||
assert_equal(l.width, 1.)
|
||||
assert_equal(l.height, 1.)
|
||||
assert_equal(l.lower_left, (1., 1.))
|
||||
assert l.width == 1.0
|
||||
assert l.height == 1.0
|
||||
assert l.lower_left == (1.0, 1.0)
|
||||
|
||||
l = AMLowerLeftLinePrimitive(22, 'on', 1, 1, (1, 1), 0)
|
||||
l = AMLowerLeftLinePrimitive(22, "on", 1, 1, (1, 1), 0)
|
||||
l.to_metric()
|
||||
assert_equal(l.width, 25.4)
|
||||
assert_equal(l.height, 25.4)
|
||||
assert_equal(l.lower_left, (25.4, 25.4))
|
||||
assert l.width == 25.4
|
||||
assert l.height == 25.4
|
||||
assert l.lower_left == (25.4, 25.4)
|
||||
|
||||
|
||||
def test_AMUnsupportPrimitive():
|
||||
u = AMUnsupportPrimitive.from_gerber('Test')
|
||||
assert_equal(u.primitive, 'Test')
|
||||
u = AMUnsupportPrimitive('Test')
|
||||
assert_equal(u.to_gerber(), 'Test')
|
||||
u = AMUnsupportPrimitive.from_gerber("Test")
|
||||
assert u.primitive == "Test"
|
||||
u = AMUnsupportPrimitive("Test")
|
||||
assert u.to_gerber() == "Test"
|
||||
|
||||
|
||||
def test_AMUnsupportPrimitive_smoketest():
|
||||
u = AMUnsupportPrimitive.from_gerber('Test')
|
||||
u = AMUnsupportPrimitive.from_gerber("Test")
|
||||
u.to_inch()
|
||||
u.to_metric()
|
||||
|
||||
|
||||
def test_inch():
|
||||
assert_equal(inch(25.4), 1)
|
||||
assert inch(25.4) == 1
|
||||
|
||||
|
||||
def test_metric():
|
||||
assert_equal(metric(1), 25.4)
|
||||
assert metric(1) == 25.4
|
||||
|
|
|
|||
|
|
@ -8,63 +8,87 @@ import tempfile
|
|||
|
||||
from ..render.cairo_backend import GerberCairoContext
|
||||
from ..rs274x import read
|
||||
from .tests import *
|
||||
from nose.tools import assert_tuple_equal
|
||||
|
||||
|
||||
def _DISABLED_test_render_two_boxes():
|
||||
"""Umaco exapmle of two boxes"""
|
||||
_test_render('resources/example_two_square_boxes.gbr', 'golden/example_two_square_boxes.png')
|
||||
_test_render(
|
||||
"resources/example_two_square_boxes.gbr", "golden/example_two_square_boxes.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_single_quadrant():
|
||||
"""Umaco exapmle of a single quadrant arc"""
|
||||
_test_render('resources/example_single_quadrant.gbr', 'golden/example_single_quadrant.png')
|
||||
_test_render(
|
||||
"resources/example_single_quadrant.gbr", "golden/example_single_quadrant.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_simple_contour():
|
||||
def _DISABLED_test_render_simple_contour():
|
||||
"""Umaco exapmle of a simple arrow-shaped contour"""
|
||||
gerber = _test_render('resources/example_simple_contour.gbr', 'golden/example_simple_contour.png')
|
||||
gerber = _test_render(
|
||||
"resources/example_simple_contour.gbr", "golden/example_simple_contour.png"
|
||||
)
|
||||
|
||||
# Check the resulting dimensions
|
||||
assert_tuple_equal(((2.0, 11.0), (1.0, 9.0)), gerber.bounding_box)
|
||||
assert ((2.0, 11.0), (1.0, 9.0)) == gerber.bounding_box
|
||||
|
||||
|
||||
def _DISABLED_test_render_single_contour_1():
|
||||
"""Umaco example of a single contour
|
||||
|
||||
The resulting image for this test is used by other tests because they must generate the same output."""
|
||||
_test_render('resources/example_single_contour_1.gbr', 'golden/example_single_contour.png')
|
||||
_test_render(
|
||||
"resources/example_single_contour_1.gbr", "golden/example_single_contour.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_single_contour_2():
|
||||
"""Umaco exapmle of a single contour, alternate contour end order
|
||||
|
||||
The resulting image for this test is used by other tests because they must generate the same output."""
|
||||
_test_render('resources/example_single_contour_2.gbr', 'golden/example_single_contour.png')
|
||||
_test_render(
|
||||
"resources/example_single_contour_2.gbr", "golden/example_single_contour.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_single_contour_3():
|
||||
"""Umaco exapmle of a single contour with extra line"""
|
||||
_test_render('resources/example_single_contour_3.gbr', 'golden/example_single_contour_3.png')
|
||||
_test_render(
|
||||
"resources/example_single_contour_3.gbr", "golden/example_single_contour_3.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_not_overlapping_contour():
|
||||
def _DISABLED_test_render_not_overlapping_contour():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_not_overlapping_contour.gbr', 'golden/example_not_overlapping_contour.png')
|
||||
_test_render(
|
||||
"resources/example_not_overlapping_contour.gbr",
|
||||
"golden/example_not_overlapping_contour.png",
|
||||
)
|
||||
|
||||
def _DISABLED_test_render_not_overlapping_touching():
|
||||
|
||||
def _DISABLED_test_render_not_overlapping_touching():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_not_overlapping_touching.gbr', 'golden/example_not_overlapping_touching.png')
|
||||
_test_render(
|
||||
"resources/example_not_overlapping_touching.gbr",
|
||||
"golden/example_not_overlapping_touching.png",
|
||||
)
|
||||
|
||||
|
||||
def test_render_overlapping_touching():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_overlapping_touching.gbr', 'golden/example_overlapping_touching.png')
|
||||
_test_render(
|
||||
"resources/example_overlapping_touching.gbr",
|
||||
"golden/example_overlapping_touching.png",
|
||||
)
|
||||
|
||||
|
||||
def test_render_overlapping_contour():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_overlapping_contour.gbr', 'golden/example_overlapping_contour.png')
|
||||
_test_render(
|
||||
"resources/example_overlapping_contour.gbr",
|
||||
"golden/example_overlapping_contour.png",
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_level_holes():
|
||||
|
|
@ -72,82 +96,107 @@ def _DISABLED_test_render_level_holes():
|
|||
|
||||
# TODO This is clearly rendering wrong. I'm temporarily checking this in because there are more
|
||||
# rendering fixes in the related repository that may resolve these.
|
||||
_test_render('resources/example_level_holes.gbr', 'golden/example_overlapping_contour.png')
|
||||
_test_render(
|
||||
"resources/example_level_holes.gbr", "golden/example_overlapping_contour.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_cutin():
|
||||
"""Umaco example of using a cutin"""
|
||||
|
||||
# TODO This is clearly rendering wrong.
|
||||
_test_render('resources/example_cutin.gbr', 'golden/example_cutin.png', '/Users/ham/Desktop/cutin.png')
|
||||
_test_render(
|
||||
"resources/example_cutin.gbr",
|
||||
"golden/example_cutin.png",
|
||||
"/Users/ham/Desktop/cutin.png",
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_fully_coincident():
|
||||
def _DISABLED_test_render_fully_coincident():
|
||||
"""Umaco example of coincident lines rendering two contours"""
|
||||
|
||||
_test_render('resources/example_fully_coincident.gbr', 'golden/example_fully_coincident.png')
|
||||
_test_render(
|
||||
"resources/example_fully_coincident.gbr", "golden/example_fully_coincident.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_coincident_hole():
|
||||
def _DISABLED_test_render_coincident_hole():
|
||||
"""Umaco example of coincident lines rendering a hole in the contour"""
|
||||
|
||||
_test_render('resources/example_coincident_hole.gbr', 'golden/example_coincident_hole.png')
|
||||
_test_render(
|
||||
"resources/example_coincident_hole.gbr", "golden/example_coincident_hole.png"
|
||||
)
|
||||
|
||||
|
||||
def test_render_cutin_multiple():
|
||||
"""Umaco example of a region with multiple cutins"""
|
||||
|
||||
_test_render('resources/example_cutin_multiple.gbr', 'golden/example_cutin_multiple.png')
|
||||
_test_render(
|
||||
"resources/example_cutin_multiple.gbr", "golden/example_cutin_multiple.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_flash_circle():
|
||||
"""Umaco example a simple circular flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_circle.gbr', 'golden/example_flash_circle.png',
|
||||
'/Users/ham/Desktop/flashcircle.png')
|
||||
_test_render(
|
||||
"resources/example_flash_circle.gbr",
|
||||
"golden/example_flash_circle.png",
|
||||
"/Users/ham/Desktop/flashcircle.png",
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_flash_rectangle():
|
||||
"""Umaco example a simple rectangular flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_rectangle.gbr', 'golden/example_flash_rectangle.png')
|
||||
_test_render(
|
||||
"resources/example_flash_rectangle.gbr", "golden/example_flash_rectangle.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_flash_obround():
|
||||
"""Umaco example a simple obround flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_obround.gbr', 'golden/example_flash_obround.png')
|
||||
_test_render(
|
||||
"resources/example_flash_obround.gbr", "golden/example_flash_obround.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_flash_polygon():
|
||||
"""Umaco example a simple polygon flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_polygon.gbr', 'golden/example_flash_polygon.png')
|
||||
_test_render(
|
||||
"resources/example_flash_polygon.gbr", "golden/example_flash_polygon.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_holes_dont_clear():
|
||||
"""Umaco example that an aperture with a hole does not clear the area"""
|
||||
|
||||
_test_render('resources/example_holes_dont_clear.gbr', 'golden/example_holes_dont_clear.png')
|
||||
_test_render(
|
||||
"resources/example_holes_dont_clear.gbr", "golden/example_holes_dont_clear.png"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_am_exposure_modifier():
|
||||
"""Umaco example that an aperture macro with a hole does not clear the area"""
|
||||
|
||||
_test_render('resources/example_am_exposure_modifier.gbr', 'golden/example_am_exposure_modifier.png')
|
||||
_test_render(
|
||||
"resources/example_am_exposure_modifier.gbr",
|
||||
"golden/example_am_exposure_modifier.png",
|
||||
)
|
||||
|
||||
|
||||
def test_render_svg_simple_contour():
|
||||
"""Example of rendering to an SVG file"""
|
||||
_test_simple_render_svg('resources/example_simple_contour.gbr')
|
||||
_test_simple_render_svg("resources/example_simple_contour.gbr")
|
||||
|
||||
|
||||
def _resolve_path(path):
|
||||
return os.path.join(os.path.dirname(__file__),
|
||||
path)
|
||||
return os.path.join(os.path.dirname(__file__), path)
|
||||
|
||||
|
||||
def _test_render(gerber_path, png_expected_path, create_output_path = None):
|
||||
def _test_render(gerber_path, png_expected_path, create_output_path=None):
|
||||
"""Render the gerber file and compare to the expected PNG output.
|
||||
|
||||
Parameters
|
||||
|
|
@ -176,21 +225,24 @@ def _test_render(gerber_path, png_expected_path, create_output_path = None):
|
|||
|
||||
# If we want to write the file bytes, do it now. This happens
|
||||
if create_output_path:
|
||||
with open(create_output_path, 'wb') as out_file:
|
||||
with open(create_output_path, "wb") as out_file:
|
||||
out_file.write(actual_bytes)
|
||||
# Creating the output is dangerous - it could overwrite the expected result.
|
||||
# So if we are creating the output, we make the test fail on purpose so you
|
||||
# won't forget to disable this
|
||||
assert_false(True, 'Test created the output %s. This needs to be disabled to make sure the test behaves correctly' % (create_output_path,))
|
||||
assert not True, (
|
||||
"Test created the output %s. This needs to be disabled to make sure the test behaves correctly"
|
||||
% (create_output_path,)
|
||||
)
|
||||
|
||||
# Read the expected PNG file
|
||||
|
||||
with open(png_expected_path, 'rb') as expected_file:
|
||||
with open(png_expected_path, "rb") as expected_file:
|
||||
expected_bytes = expected_file.read()
|
||||
|
||||
# Don't directly use assert_equal otherwise any failure pollutes the test results
|
||||
equal = (expected_bytes == actual_bytes)
|
||||
assert_true(equal)
|
||||
equal = expected_bytes == actual_bytes
|
||||
assert equal
|
||||
|
||||
return gerber
|
||||
|
||||
|
|
@ -214,14 +266,14 @@ def _test_simple_render_svg(gerber_path):
|
|||
gerber.render(ctx)
|
||||
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
svg_temp_path = os.path.join(temp_dir, 'output.svg')
|
||||
svg_temp_path = os.path.join(temp_dir, "output.svg")
|
||||
|
||||
assert_false(os.path.exists(svg_temp_path))
|
||||
assert not os.path.exists(svg_temp_path)
|
||||
ctx.dump(svg_temp_path)
|
||||
assert_true(os.path.exists(svg_temp_path))
|
||||
assert os.path.exists(svg_temp_path)
|
||||
|
||||
with open(svg_temp_path, 'r') as expected_file:
|
||||
with open(svg_temp_path, "r") as expected_file:
|
||||
expected_bytes = expected_file.read()
|
||||
assert_equal(expected_bytes[:38], '<?xml version="1.0" encoding="UTF-8"?>')
|
||||
assert expected_bytes[:38] == '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
|
||||
shutil.rmtree(temp_dir)
|
||||
|
|
|
|||
|
|
@ -3,56 +3,57 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
import pytest
|
||||
|
||||
from ..cam import CamFile, FileSettings
|
||||
from .tests import *
|
||||
|
||||
|
||||
def test_filesettings_defaults():
|
||||
""" Test FileSettings default values
|
||||
"""
|
||||
fs = FileSettings()
|
||||
assert_equal(fs.format, (2, 5))
|
||||
assert_equal(fs.notation, 'absolute')
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
assert_equal(fs.units, 'inch')
|
||||
assert fs.format == (2, 5)
|
||||
assert fs.notation == "absolute"
|
||||
assert fs.zero_suppression == "trailing"
|
||||
assert fs.units == "inch"
|
||||
|
||||
|
||||
def test_filesettings_dict():
|
||||
""" Test FileSettings Dict
|
||||
"""
|
||||
fs = FileSettings()
|
||||
assert_equal(fs['format'], (2, 5))
|
||||
assert_equal(fs['notation'], 'absolute')
|
||||
assert_equal(fs['zero_suppression'], 'trailing')
|
||||
assert_equal(fs['units'], 'inch')
|
||||
assert fs["format"] == (2, 5)
|
||||
assert fs["notation"] == "absolute"
|
||||
assert fs["zero_suppression"] == "trailing"
|
||||
assert fs["units"] == "inch"
|
||||
|
||||
|
||||
def test_filesettings_assign():
|
||||
""" Test FileSettings attribute assignment
|
||||
"""
|
||||
fs = FileSettings()
|
||||
fs.units = 'test1'
|
||||
fs.notation = 'test2'
|
||||
fs.zero_suppression = 'test3'
|
||||
fs.format = 'test4'
|
||||
assert_equal(fs.units, 'test1')
|
||||
assert_equal(fs.notation, 'test2')
|
||||
assert_equal(fs.zero_suppression, 'test3')
|
||||
assert_equal(fs.format, 'test4')
|
||||
fs.units = "test1"
|
||||
fs.notation = "test2"
|
||||
fs.zero_suppression = "test3"
|
||||
fs.format = "test4"
|
||||
assert fs.units == "test1"
|
||||
assert fs.notation == "test2"
|
||||
assert fs.zero_suppression == "test3"
|
||||
assert fs.format == "test4"
|
||||
|
||||
|
||||
def test_filesettings_dict_assign():
|
||||
""" Test FileSettings dict-style attribute assignment
|
||||
"""
|
||||
fs = FileSettings()
|
||||
fs['units'] = 'metric'
|
||||
fs['notation'] = 'incremental'
|
||||
fs['zero_suppression'] = 'leading'
|
||||
fs['format'] = (1, 2)
|
||||
assert_equal(fs.units, 'metric')
|
||||
assert_equal(fs.notation, 'incremental')
|
||||
assert_equal(fs.zero_suppression, 'leading')
|
||||
assert_equal(fs.format, (1, 2))
|
||||
fs["units"] = "metric"
|
||||
fs["notation"] = "incremental"
|
||||
fs["zero_suppression"] = "leading"
|
||||
fs["format"] = (1, 2)
|
||||
assert fs.units == "metric"
|
||||
assert fs.notation == "incremental"
|
||||
assert fs.zero_suppression == "leading"
|
||||
assert fs.format == (1, 2)
|
||||
|
||||
|
||||
def test_camfile_init():
|
||||
|
|
@ -65,7 +66,7 @@ def test_camfile_settings():
|
|||
""" Test CamFile Default Settings
|
||||
"""
|
||||
cf = CamFile()
|
||||
assert_equal(cf.settings, FileSettings())
|
||||
assert cf.settings == FileSettings()
|
||||
|
||||
|
||||
def test_bounds_override_smoketest():
|
||||
|
|
@ -77,73 +78,74 @@ def test_zeros():
|
|||
""" Test zero/zero_suppression interaction
|
||||
"""
|
||||
fs = FileSettings()
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
assert_equal(fs.zeros, 'leading')
|
||||
assert fs.zero_suppression == "trailing"
|
||||
assert fs.zeros == "leading"
|
||||
|
||||
fs['zero_suppression'] = 'leading'
|
||||
assert_equal(fs.zero_suppression, 'leading')
|
||||
assert_equal(fs.zeros, 'trailing')
|
||||
fs["zero_suppression"] = "leading"
|
||||
assert fs.zero_suppression == "leading"
|
||||
assert fs.zeros == "trailing"
|
||||
|
||||
fs.zero_suppression = 'trailing'
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
assert_equal(fs.zeros, 'leading')
|
||||
fs.zero_suppression = "trailing"
|
||||
assert fs.zero_suppression == "trailing"
|
||||
assert fs.zeros == "leading"
|
||||
|
||||
fs['zeros'] = 'trailing'
|
||||
assert_equal(fs.zeros, 'trailing')
|
||||
assert_equal(fs.zero_suppression, 'leading')
|
||||
fs["zeros"] = "trailing"
|
||||
assert fs.zeros == "trailing"
|
||||
assert fs.zero_suppression == "leading"
|
||||
|
||||
fs.zeros = 'leading'
|
||||
assert_equal(fs.zeros, 'leading')
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
fs.zeros = "leading"
|
||||
assert fs.zeros == "leading"
|
||||
assert fs.zero_suppression == "trailing"
|
||||
|
||||
fs = FileSettings(zeros='leading')
|
||||
assert_equal(fs.zeros, 'leading')
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
fs = FileSettings(zeros="leading")
|
||||
assert fs.zeros == "leading"
|
||||
assert fs.zero_suppression == "trailing"
|
||||
|
||||
fs = FileSettings(zero_suppression='leading')
|
||||
assert_equal(fs.zeros, 'trailing')
|
||||
assert_equal(fs.zero_suppression, 'leading')
|
||||
fs = FileSettings(zero_suppression="leading")
|
||||
assert fs.zeros == "trailing"
|
||||
assert fs.zero_suppression == "leading"
|
||||
|
||||
fs = FileSettings(zeros='leading', zero_suppression='trailing')
|
||||
assert_equal(fs.zeros, 'leading')
|
||||
assert_equal(fs.zero_suppression, 'trailing')
|
||||
fs = FileSettings(zeros="leading", zero_suppression="trailing")
|
||||
assert fs.zeros == "leading"
|
||||
assert fs.zero_suppression == "trailing"
|
||||
|
||||
fs = FileSettings(zeros='trailing', zero_suppression='leading')
|
||||
assert_equal(fs.zeros, 'trailing')
|
||||
assert_equal(fs.zero_suppression, 'leading')
|
||||
fs = FileSettings(zeros="trailing", zero_suppression="leading")
|
||||
assert fs.zeros == "trailing"
|
||||
assert fs.zero_suppression == "leading"
|
||||
|
||||
|
||||
def test_filesettings_validation():
|
||||
""" Test FileSettings constructor argument validation
|
||||
"""
|
||||
# absolute-ish is not a valid notation
|
||||
assert_raises(ValueError, FileSettings, 'absolute-ish',
|
||||
'inch', None, (2, 5), None)
|
||||
pytest.raises(ValueError, FileSettings, "absolute-ish", "inch", None, (2, 5), None)
|
||||
|
||||
# degrees kelvin isn't a valid unit for a CAM file
|
||||
assert_raises(ValueError, FileSettings, 'absolute',
|
||||
'degrees kelvin', None, (2, 5), None)
|
||||
pytest.raises(
|
||||
ValueError, FileSettings, "absolute", "degrees kelvin", None, (2, 5), None
|
||||
)
|
||||
|
||||
assert_raises(ValueError, FileSettings, 'absolute',
|
||||
'inch', 'leading', (2, 5), 'leading')
|
||||
pytest.raises(
|
||||
ValueError, FileSettings, "absolute", "inch", "leading", (2, 5), "leading"
|
||||
)
|
||||
|
||||
# Technnically this should be an error, but Eangle files often do this incorrectly so we
|
||||
# allow it
|
||||
#assert_raises(ValueError, FileSettings, 'absolute',
|
||||
# pytest.raises(ValueError, FileSettings, 'absolute',
|
||||
# 'inch', 'following', (2, 5), None)
|
||||
|
||||
assert_raises(ValueError, FileSettings, 'absolute',
|
||||
'inch', None, (2, 5), 'following')
|
||||
assert_raises(ValueError, FileSettings, 'absolute',
|
||||
'inch', None, (2, 5, 6), None)
|
||||
pytest.raises(
|
||||
ValueError, FileSettings, "absolute", "inch", None, (2, 5), "following"
|
||||
)
|
||||
pytest.raises(ValueError, FileSettings, "absolute", "inch", None, (2, 5, 6), None)
|
||||
|
||||
|
||||
def test_key_validation():
|
||||
fs = FileSettings()
|
||||
assert_raises(KeyError, fs.__getitem__, 'octopus')
|
||||
assert_raises(KeyError, fs.__setitem__, 'octopus', 'do not care')
|
||||
assert_raises(ValueError, fs.__setitem__, 'notation', 'absolute-ish')
|
||||
assert_raises(ValueError, fs.__setitem__, 'units', 'degrees kelvin')
|
||||
assert_raises(ValueError, fs.__setitem__, 'zero_suppression', 'following')
|
||||
assert_raises(ValueError, fs.__setitem__, 'zeros', 'following')
|
||||
assert_raises(ValueError, fs.__setitem__, 'format', (2, 5, 6))
|
||||
pytest.raises(KeyError, fs.__getitem__, "octopus")
|
||||
pytest.raises(KeyError, fs.__setitem__, "octopus", "do not care")
|
||||
pytest.raises(ValueError, fs.__setitem__, "notation", "absolute-ish")
|
||||
pytest.raises(ValueError, fs.__setitem__, "units", "degrees kelvin")
|
||||
pytest.raises(ValueError, fs.__setitem__, "zero_suppression", "following")
|
||||
pytest.raises(ValueError, fs.__setitem__, "zeros", "following")
|
||||
pytest.raises(ValueError, fs.__setitem__, "format", (2, 5, 6))
|
||||
|
|
|
|||
|
|
@ -6,15 +6,12 @@ from ..exceptions import ParseError
|
|||
from ..common import read, loads
|
||||
from ..excellon import ExcellonFile
|
||||
from ..rs274x import GerberFile
|
||||
from .tests import *
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/ncdrill.DRD')
|
||||
TOP_COPPER_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/top_copper.GTL')
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__), "resources/ncdrill.DRD")
|
||||
TOP_COPPER_FILE = os.path.join(os.path.dirname(__file__), "resources/top_copper.GTL")
|
||||
|
||||
|
||||
def test_file_type_detection():
|
||||
|
|
@ -22,20 +19,20 @@ def test_file_type_detection():
|
|||
"""
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
top_copper = read(TOP_COPPER_FILE)
|
||||
assert_true(isinstance(ncdrill, ExcellonFile))
|
||||
assert_true(isinstance(top_copper, GerberFile))
|
||||
assert isinstance(ncdrill, ExcellonFile)
|
||||
assert isinstance(top_copper, GerberFile)
|
||||
|
||||
|
||||
def test_load_from_string():
|
||||
with open(NCDRILL_FILE, 'rU') as f:
|
||||
with open(NCDRILL_FILE, "rU") as f:
|
||||
ncdrill = loads(f.read())
|
||||
with open(TOP_COPPER_FILE, 'rU') as f:
|
||||
with open(TOP_COPPER_FILE, "rU") as f:
|
||||
top_copper = loads(f.read())
|
||||
assert_true(isinstance(ncdrill, ExcellonFile))
|
||||
assert_true(isinstance(top_copper, GerberFile))
|
||||
assert isinstance(ncdrill, ExcellonFile)
|
||||
assert isinstance(top_copper, GerberFile)
|
||||
|
||||
|
||||
def test_file_type_validation():
|
||||
""" Test file format validation
|
||||
"""
|
||||
assert_raises(ParseError, read, __file__)
|
||||
pytest.raises(ParseError, read, __file__)
|
||||
|
|
|
|||
|
|
@ -3,16 +3,15 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from ..cam import FileSettings
|
||||
from ..excellon import read, detect_excellon_format, ExcellonFile, ExcellonParser
|
||||
from ..excellon import DrillHit, DrillSlot
|
||||
from ..excellon_statements import ExcellonTool, RouteModeStmt
|
||||
from .tests import *
|
||||
|
||||
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/ncdrill.DRD')
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__), "resources/ncdrill.DRD")
|
||||
|
||||
|
||||
def test_format_detection():
|
||||
|
|
@ -21,320 +20,327 @@ def test_format_detection():
|
|||
with open(NCDRILL_FILE, "rU") as f:
|
||||
data = f.read()
|
||||
settings = detect_excellon_format(data)
|
||||
assert_equal(settings['format'], (2, 4))
|
||||
assert_equal(settings['zeros'], 'trailing')
|
||||
assert settings["format"] == (2, 4)
|
||||
assert settings["zeros"] == "trailing"
|
||||
|
||||
settings = detect_excellon_format(filename=NCDRILL_FILE)
|
||||
assert_equal(settings['format'], (2, 4))
|
||||
assert_equal(settings['zeros'], 'trailing')
|
||||
assert settings["format"] == (2, 4)
|
||||
assert settings["zeros"] == "trailing"
|
||||
|
||||
|
||||
def test_read():
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
assert(isinstance(ncdrill, ExcellonFile))
|
||||
assert isinstance(ncdrill, ExcellonFile)
|
||||
|
||||
|
||||
def test_write():
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
ncdrill.write('test.ncd')
|
||||
ncdrill.write("test.ncd")
|
||||
with open(NCDRILL_FILE, "rU") as src:
|
||||
srclines = src.readlines()
|
||||
with open('test.ncd', "rU") as res:
|
||||
with open("test.ncd", "rU") as res:
|
||||
for idx, line in enumerate(res):
|
||||
assert_equal(line.strip(), srclines[idx].strip())
|
||||
os.remove('test.ncd')
|
||||
assert line.strip() == srclines[idx].strip()
|
||||
os.remove("test.ncd")
|
||||
|
||||
|
||||
def test_read_settings():
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
assert_equal(ncdrill.settings['format'], (2, 4))
|
||||
assert_equal(ncdrill.settings['zeros'], 'trailing')
|
||||
assert ncdrill.settings["format"] == (2, 4)
|
||||
assert ncdrill.settings["zeros"] == "trailing"
|
||||
|
||||
|
||||
def test_bounding_box():
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
xbound, ybound = ncdrill.bounding_box
|
||||
assert_array_almost_equal(xbound, (0.1300, 2.1430))
|
||||
assert_array_almost_equal(ybound, (0.3946, 1.7164))
|
||||
pytest.approx(xbound, (0.1300, 2.1430))
|
||||
pytest.approx(ybound, (0.3946, 1.7164))
|
||||
|
||||
|
||||
def test_report():
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
rprt = ncdrill.report()
|
||||
|
||||
|
||||
def test_conversion():
|
||||
import copy
|
||||
|
||||
ncdrill = read(NCDRILL_FILE)
|
||||
assert_equal(ncdrill.settings.units, 'inch')
|
||||
assert ncdrill.settings.units == "inch"
|
||||
ncdrill_inch = copy.deepcopy(ncdrill)
|
||||
|
||||
ncdrill.to_metric()
|
||||
assert_equal(ncdrill.settings.units, 'metric')
|
||||
assert ncdrill.settings.units == "metric"
|
||||
for tool in iter(ncdrill_inch.tools.values()):
|
||||
tool.to_metric()
|
||||
|
||||
for statement in ncdrill_inch.statements:
|
||||
statement.to_metric()
|
||||
|
||||
for m_tool, i_tool in zip(iter(ncdrill.tools.values()),
|
||||
iter(ncdrill_inch.tools.values())):
|
||||
assert_equal(i_tool, m_tool)
|
||||
for m_tool, i_tool in zip(
|
||||
iter(ncdrill.tools.values()), iter(ncdrill_inch.tools.values())
|
||||
):
|
||||
assert i_tool == m_tool
|
||||
|
||||
for m, i in zip(ncdrill.primitives, ncdrill_inch.primitives):
|
||||
|
||||
assert_equal(m.position, i.position, '%s not equal to %s' % (m, i))
|
||||
assert_equal(m.diameter, i.diameter, '%s not equal to %s' % (m, i))
|
||||
assert m.position == i.position, "%s not equal to %s" % (m, i)
|
||||
assert m.diameter == i.diameter, "%s not equal to %s" % (m, i)
|
||||
|
||||
|
||||
def test_parser_hole_count():
|
||||
settings = FileSettings(**detect_excellon_format(NCDRILL_FILE))
|
||||
p = ExcellonParser(settings)
|
||||
p.parse(NCDRILL_FILE)
|
||||
assert_equal(p.hole_count, 36)
|
||||
assert p.hole_count == 36
|
||||
|
||||
|
||||
def test_parser_hole_sizes():
|
||||
settings = FileSettings(**detect_excellon_format(NCDRILL_FILE))
|
||||
p = ExcellonParser(settings)
|
||||
p.parse(NCDRILL_FILE)
|
||||
assert_equal(p.hole_sizes, [0.0236, 0.0354, 0.04, 0.126, 0.128])
|
||||
assert p.hole_sizes == [0.0236, 0.0354, 0.04, 0.126, 0.128]
|
||||
|
||||
|
||||
def test_parse_whitespace():
|
||||
p = ExcellonParser(FileSettings())
|
||||
assert_equal(p._parse_line(' '), None)
|
||||
assert p._parse_line(" ") == None
|
||||
|
||||
|
||||
def test_parse_comment():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line(';A comment')
|
||||
assert_equal(p.statements[0].comment, 'A comment')
|
||||
p._parse_line(";A comment")
|
||||
assert p.statements[0].comment == "A comment"
|
||||
|
||||
|
||||
def test_parse_format_comment():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('; FILE_FORMAT=9:9 ')
|
||||
assert_equal(p.format, (9, 9))
|
||||
p._parse_line("; FILE_FORMAT=9:9 ")
|
||||
assert p.format == (9, 9)
|
||||
|
||||
|
||||
def test_parse_header():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('M48 ')
|
||||
assert_equal(p.state, 'HEADER')
|
||||
p._parse_line('M95 ')
|
||||
assert_equal(p.state, 'DRILL')
|
||||
p._parse_line("M48 ")
|
||||
assert p.state == "HEADER"
|
||||
p._parse_line("M95 ")
|
||||
assert p.state == "DRILL"
|
||||
|
||||
|
||||
def test_parse_rout():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('G00X040944Y019842')
|
||||
assert_equal(p.state, 'ROUT')
|
||||
p._parse_line('G05 ')
|
||||
assert_equal(p.state, 'DRILL')
|
||||
p._parse_line("G00X040944Y019842")
|
||||
assert p.state == "ROUT"
|
||||
p._parse_line("G05 ")
|
||||
assert p.state == "DRILL"
|
||||
|
||||
|
||||
def test_parse_version():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('VER,1 ')
|
||||
assert_equal(p.statements[0].version, 1)
|
||||
p._parse_line('VER,2 ')
|
||||
assert_equal(p.statements[1].version, 2)
|
||||
p._parse_line("VER,1 ")
|
||||
assert p.statements[0].version == 1
|
||||
p._parse_line("VER,2 ")
|
||||
assert p.statements[1].version == 2
|
||||
|
||||
|
||||
def test_parse_format():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('FMAT,1 ')
|
||||
assert_equal(p.statements[0].format, 1)
|
||||
p._parse_line('FMAT,2 ')
|
||||
assert_equal(p.statements[1].format, 2)
|
||||
p._parse_line("FMAT,1 ")
|
||||
assert p.statements[0].format == 1
|
||||
p._parse_line("FMAT,2 ")
|
||||
assert p.statements[1].format == 2
|
||||
|
||||
|
||||
def test_parse_units():
|
||||
settings = FileSettings(units='inch', zeros='trailing')
|
||||
settings = FileSettings(units="inch", zeros="trailing")
|
||||
p = ExcellonParser(settings)
|
||||
p._parse_line(';METRIC,LZ')
|
||||
assert_equal(p.units, 'inch')
|
||||
assert_equal(p.zeros, 'trailing')
|
||||
p._parse_line('METRIC,LZ')
|
||||
assert_equal(p.units, 'metric')
|
||||
assert_equal(p.zeros, 'leading')
|
||||
p._parse_line(";METRIC,LZ")
|
||||
assert p.units == "inch"
|
||||
assert p.zeros == "trailing"
|
||||
p._parse_line("METRIC,LZ")
|
||||
assert p.units == "metric"
|
||||
assert p.zeros == "leading"
|
||||
|
||||
|
||||
def test_parse_incremental_mode():
|
||||
settings = FileSettings(units='inch', zeros='trailing')
|
||||
settings = FileSettings(units="inch", zeros="trailing")
|
||||
p = ExcellonParser(settings)
|
||||
assert_equal(p.notation, 'absolute')
|
||||
p._parse_line('ICI,ON ')
|
||||
assert_equal(p.notation, 'incremental')
|
||||
p._parse_line('ICI,OFF ')
|
||||
assert_equal(p.notation, 'absolute')
|
||||
assert p.notation == "absolute"
|
||||
p._parse_line("ICI,ON ")
|
||||
assert p.notation == "incremental"
|
||||
p._parse_line("ICI,OFF ")
|
||||
assert p.notation == "absolute"
|
||||
|
||||
|
||||
def test_parse_absolute_mode():
|
||||
settings = FileSettings(units='inch', zeros='trailing')
|
||||
settings = FileSettings(units="inch", zeros="trailing")
|
||||
p = ExcellonParser(settings)
|
||||
assert_equal(p.notation, 'absolute')
|
||||
p._parse_line('ICI,ON ')
|
||||
assert_equal(p.notation, 'incremental')
|
||||
p._parse_line('G90 ')
|
||||
assert_equal(p.notation, 'absolute')
|
||||
assert p.notation == "absolute"
|
||||
p._parse_line("ICI,ON ")
|
||||
assert p.notation == "incremental"
|
||||
p._parse_line("G90 ")
|
||||
assert p.notation == "absolute"
|
||||
|
||||
|
||||
def test_parse_repeat_hole():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p.active_tool = ExcellonTool(FileSettings(), number=8)
|
||||
p._parse_line('R03X1.5Y1.5')
|
||||
assert_equal(p.statements[0].count, 3)
|
||||
p._parse_line("R03X1.5Y1.5")
|
||||
assert p.statements[0].count == 3
|
||||
|
||||
|
||||
def test_parse_incremental_position():
|
||||
p = ExcellonParser(FileSettings(notation='incremental'))
|
||||
p._parse_line('X01Y01')
|
||||
p._parse_line('X01Y01')
|
||||
assert_equal(p.pos, [2., 2.])
|
||||
p = ExcellonParser(FileSettings(notation="incremental"))
|
||||
p._parse_line("X01Y01")
|
||||
p._parse_line("X01Y01")
|
||||
assert p.pos == [2.0, 2.0]
|
||||
|
||||
|
||||
def test_parse_unknown():
|
||||
p = ExcellonParser(FileSettings())
|
||||
p._parse_line('Not A Valid Statement')
|
||||
assert_equal(p.statements[0].stmt, 'Not A Valid Statement')
|
||||
p._parse_line("Not A Valid Statement")
|
||||
assert p.statements[0].stmt == "Not A Valid Statement"
|
||||
|
||||
|
||||
def test_drill_hit_units_conversion():
|
||||
""" Test unit conversion for drill hits
|
||||
"""
|
||||
# Inch hit
|
||||
settings = FileSettings(units='inch')
|
||||
settings = FileSettings(units="inch")
|
||||
tool = ExcellonTool(settings, diameter=1.0)
|
||||
hit = DrillHit(tool, (1.0, 1.0))
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.position, (1.0, 1.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.position == (1.0, 1.0)
|
||||
|
||||
# No Effect
|
||||
hit.to_inch()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.position, (1.0, 1.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.position == (1.0, 1.0)
|
||||
|
||||
# Should convert
|
||||
hit.to_metric()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'metric')
|
||||
assert_equal(hit.tool.diameter, 25.4)
|
||||
assert_equal(hit.position, (25.4, 25.4))
|
||||
assert hit.tool.settings.units == "metric"
|
||||
assert hit.tool.diameter == 25.4
|
||||
assert hit.position == (25.4, 25.4)
|
||||
|
||||
# No Effect
|
||||
hit.to_metric()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'metric')
|
||||
assert_equal(hit.tool.diameter, 25.4)
|
||||
assert_equal(hit.position, (25.4, 25.4))
|
||||
assert hit.tool.settings.units == "metric"
|
||||
assert hit.tool.diameter == 25.4
|
||||
assert hit.position == (25.4, 25.4)
|
||||
|
||||
# Convert back to inch
|
||||
hit.to_inch()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.position, (1.0, 1.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.position == (1.0, 1.0)
|
||||
|
||||
|
||||
def test_drill_hit_offset():
|
||||
TEST_VECTORS = [
|
||||
((0.0 ,0.0), (0.0, 1.0), (0.0, 1.0)),
|
||||
((0.0, 0.0), (0.0, 1.0), (0.0, 1.0)),
|
||||
((0.0, 0.0), (1.0, 1.0), (1.0, 1.0)),
|
||||
((1.0, 1.0), (0.0, -1.0), (1.0, 0.0)),
|
||||
((1.0, 1.0), (-1.0, -1.0), (0.0, 0.0)),
|
||||
|
||||
]
|
||||
for position, offset, expected in TEST_VECTORS:
|
||||
settings = FileSettings(units='inch')
|
||||
settings = FileSettings(units="inch")
|
||||
tool = ExcellonTool(settings, diameter=1.0)
|
||||
hit = DrillHit(tool, position)
|
||||
|
||||
assert_equal(hit.position, position)
|
||||
assert hit.position == position
|
||||
|
||||
hit.offset(offset[0], offset[1])
|
||||
|
||||
assert_equal(hit.position, expected)
|
||||
assert hit.position == expected
|
||||
|
||||
|
||||
def test_drill_slot_units_conversion():
|
||||
""" Test unit conversion for drill hits
|
||||
"""
|
||||
# Inch hit
|
||||
settings = FileSettings(units='inch')
|
||||
settings = FileSettings(units="inch")
|
||||
tool = ExcellonTool(settings, diameter=1.0)
|
||||
hit = DrillSlot(tool, (1.0, 1.0), (10.0, 10.0), DrillSlot.TYPE_ROUT)
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.start, (1.0, 1.0))
|
||||
assert_equal(hit.end, (10.0, 10.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.start == (1.0, 1.0)
|
||||
assert hit.end == (10.0, 10.0)
|
||||
|
||||
# No Effect
|
||||
hit.to_inch()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.start, (1.0, 1.0))
|
||||
assert_equal(hit.end, (10.0, 10.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.start == (1.0, 1.0)
|
||||
assert hit.end == (10.0, 10.0)
|
||||
|
||||
# Should convert
|
||||
hit.to_metric()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'metric')
|
||||
assert_equal(hit.tool.diameter, 25.4)
|
||||
assert_equal(hit.start, (25.4, 25.4))
|
||||
assert_equal(hit.end, (254.0, 254.0))
|
||||
assert hit.tool.settings.units == "metric"
|
||||
assert hit.tool.diameter == 25.4
|
||||
assert hit.start == (25.4, 25.4)
|
||||
assert hit.end == (254.0, 254.0)
|
||||
|
||||
# No Effect
|
||||
hit.to_metric()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'metric')
|
||||
assert_equal(hit.tool.diameter, 25.4)
|
||||
assert_equal(hit.start, (25.4, 25.4))
|
||||
assert_equal(hit.end, (254.0, 254.0))
|
||||
assert hit.tool.settings.units == "metric"
|
||||
assert hit.tool.diameter == 25.4
|
||||
assert hit.start == (25.4, 25.4)
|
||||
assert hit.end == (254.0, 254.0)
|
||||
|
||||
# Convert back to inch
|
||||
hit.to_inch()
|
||||
|
||||
assert_equal(hit.tool.settings.units, 'inch')
|
||||
assert_equal(hit.tool.diameter, 1.0)
|
||||
assert_equal(hit.start, (1.0, 1.0))
|
||||
assert_equal(hit.end, (10.0, 10.0))
|
||||
assert hit.tool.settings.units == "inch"
|
||||
assert hit.tool.diameter == 1.0
|
||||
assert hit.start == (1.0, 1.0)
|
||||
assert hit.end == (10.0, 10.0)
|
||||
|
||||
|
||||
def test_drill_slot_offset():
|
||||
TEST_VECTORS = [
|
||||
((0.0 ,0.0), (1.0, 1.0), (0.0, 0.0), (0.0, 0.0), (1.0, 1.0)),
|
||||
((0.0, 0.0), (1.0, 1.0), (0.0, 0.0), (0.0, 0.0), (1.0, 1.0)),
|
||||
((0.0, 0.0), (1.0, 1.0), (1.0, 0.0), (1.0, 0.0), (2.0, 1.0)),
|
||||
((0.0, 0.0), (1.0, 1.0), (1.0, 1.0), (1.0, 1.0), (2.0, 2.0)),
|
||||
((0.0, 0.0), (1.0, 1.0), (-1.0, 1.0), (-1.0, 1.0), (0.0, 2.0)),
|
||||
]
|
||||
for start, end, offset, expected_start, expected_end in TEST_VECTORS:
|
||||
settings = FileSettings(units='inch')
|
||||
settings = FileSettings(units="inch")
|
||||
tool = ExcellonTool(settings, diameter=1.0)
|
||||
slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT)
|
||||
|
||||
assert_equal(slot.start, start)
|
||||
assert_equal(slot.end, end)
|
||||
assert slot.start == start
|
||||
assert slot.end == end
|
||||
|
||||
slot.offset(offset[0], offset[1])
|
||||
|
||||
assert_equal(slot.start, expected_start)
|
||||
assert_equal(slot.end, expected_end)
|
||||
assert slot.start == expected_start
|
||||
assert slot.end == expected_end
|
||||
|
||||
|
||||
def test_drill_slot_bounds():
|
||||
TEST_VECTORS = [
|
||||
((0.0, 0.0), (1.0, 1.0), 1.0, ((-0.5, 1.5), (-0.5, 1.5))),
|
||||
((0.0, 0.0), (1.0, 1.0), 0.5, ((-0.25, 1.25), (-0.25, 1.25))),
|
||||
]
|
||||
for start, end, diameter, expected, in TEST_VECTORS:
|
||||
settings = FileSettings(units='inch')
|
||||
for start, end, diameter, expected in TEST_VECTORS:
|
||||
settings = FileSettings(units="inch")
|
||||
tool = ExcellonTool(settings, diameter=diameter)
|
||||
slot = DrillSlot(tool, start, end, DrillSlot.TYPE_ROUT)
|
||||
|
||||
assert_equal(slot.bounding_box, expected)
|
||||
assert slot.bounding_box == expected
|
||||
|
||||
|
||||
def test_handling_multi_line_g00_and_g1():
|
||||
"""Route Mode statements with coordinates on separate line are handled
|
||||
|
|
@ -355,6 +361,6 @@ M16
|
|||
"""
|
||||
uut = ExcellonParser()
|
||||
uut.parse_raw(test_data)
|
||||
assert_equal(len([stmt for stmt in uut.statements
|
||||
if isinstance(stmt, RouteModeStmt)]), 2)
|
||||
|
||||
assert (
|
||||
len([stmt for stmt in uut.statements if isinstance(stmt, RouteModeStmt)]) == 2
|
||||
)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2,139 +2,147 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
import pytest
|
||||
from ..ipc356 import *
|
||||
from ..cam import FileSettings
|
||||
from .tests import *
|
||||
|
||||
import os
|
||||
|
||||
IPC_D_356_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/ipc-d-356.ipc')
|
||||
IPC_D_356_FILE = os.path.join(os.path.dirname(__file__), "resources/ipc-d-356.ipc")
|
||||
|
||||
|
||||
def test_read():
|
||||
ipcfile = read(IPC_D_356_FILE)
|
||||
assert(isinstance(ipcfile, IPCNetlist))
|
||||
|
||||
assert isinstance(ipcfile, IPCNetlist)
|
||||
|
||||
|
||||
def test_parser():
|
||||
ipcfile = read(IPC_D_356_FILE)
|
||||
assert_equal(ipcfile.settings.units, 'inch')
|
||||
assert_equal(ipcfile.settings.angle_units, 'degrees')
|
||||
assert_equal(len(ipcfile.comments), 3)
|
||||
assert_equal(len(ipcfile.parameters), 4)
|
||||
assert_equal(len(ipcfile.test_records), 105)
|
||||
assert_equal(len(ipcfile.components), 21)
|
||||
assert_equal(len(ipcfile.vias), 14)
|
||||
assert_equal(ipcfile.test_records[-1].net_name, 'A_REALLY_LONG_NET_NAME')
|
||||
assert_equal(ipcfile.outlines[0].type, 'BOARD_EDGE')
|
||||
assert_equal(set(ipcfile.outlines[0].points),
|
||||
{(0., 0.), (2.25, 0.), (2.25, 1.5), (0., 1.5), (0.13, 0.024)})
|
||||
assert ipcfile.settings.units == "inch"
|
||||
assert ipcfile.settings.angle_units == "degrees"
|
||||
assert len(ipcfile.comments) == 3
|
||||
assert len(ipcfile.parameters) == 4
|
||||
assert len(ipcfile.test_records) == 105
|
||||
assert len(ipcfile.components) == 21
|
||||
assert len(ipcfile.vias) == 14
|
||||
assert ipcfile.test_records[-1].net_name == "A_REALLY_LONG_NET_NAME"
|
||||
assert ipcfile.outlines[0].type == "BOARD_EDGE"
|
||||
assert set(ipcfile.outlines[0].points) == {
|
||||
(0.0, 0.0),
|
||||
(2.25, 0.0),
|
||||
(2.25, 1.5),
|
||||
(0.0, 1.5),
|
||||
(0.13, 0.024),
|
||||
}
|
||||
|
||||
|
||||
def test_comment():
|
||||
c = IPC356_Comment('Layer Stackup:')
|
||||
assert_equal(c.comment, 'Layer Stackup:')
|
||||
c = IPC356_Comment.from_line('C Layer Stackup: ')
|
||||
assert_equal(c.comment, 'Layer Stackup:')
|
||||
assert_raises(ValueError, IPC356_Comment.from_line, 'P JOB')
|
||||
assert_equal(str(c), '<IPC-D-356 Comment: Layer Stackup:>')
|
||||
c = IPC356_Comment("Layer Stackup:")
|
||||
assert c.comment == "Layer Stackup:"
|
||||
c = IPC356_Comment.from_line("C Layer Stackup: ")
|
||||
assert c.comment == "Layer Stackup:"
|
||||
pytest.raises(ValueError, IPC356_Comment.from_line, "P JOB")
|
||||
assert str(c) == "<IPC-D-356 Comment: Layer Stackup:>"
|
||||
|
||||
|
||||
def test_parameter():
|
||||
p = IPC356_Parameter('VER', 'IPC-D-356A')
|
||||
assert_equal(p.parameter, 'VER')
|
||||
assert_equal(p.value, 'IPC-D-356A')
|
||||
p = IPC356_Parameter.from_line('P VER IPC-D-356A ')
|
||||
assert_equal(p.parameter, 'VER')
|
||||
assert_equal(p.value, 'IPC-D-356A')
|
||||
assert_raises(ValueError, IPC356_Parameter.from_line,
|
||||
'C Layer Stackup: ')
|
||||
assert_equal(str(p), '<IPC-D-356 Parameter: VER=IPC-D-356A>')
|
||||
p = IPC356_Parameter("VER", "IPC-D-356A")
|
||||
assert p.parameter == "VER"
|
||||
assert p.value == "IPC-D-356A"
|
||||
p = IPC356_Parameter.from_line("P VER IPC-D-356A ")
|
||||
assert p.parameter == "VER"
|
||||
assert p.value == "IPC-D-356A"
|
||||
pytest.raises(ValueError, IPC356_Parameter.from_line, "C Layer Stackup: ")
|
||||
assert str(p) == "<IPC-D-356 Parameter: VER=IPC-D-356A>"
|
||||
|
||||
|
||||
def test_eof():
|
||||
e = IPC356_EndOfFile()
|
||||
assert_equal(e.to_netlist(), '999')
|
||||
assert_equal(str(e), '<IPC-D-356 EOF>')
|
||||
assert e.to_netlist() == "999"
|
||||
assert str(e) == "<IPC-D-356 EOF>"
|
||||
|
||||
|
||||
def test_outline():
|
||||
type = 'BOARD_EDGE'
|
||||
points = [(0.01, 0.01), (2., 2.), (4., 2.), (4., 6.)]
|
||||
type = "BOARD_EDGE"
|
||||
points = [(0.01, 0.01), (2.0, 2.0), (4.0, 2.0), (4.0, 6.0)]
|
||||
b = IPC356_Outline(type, points)
|
||||
assert_equal(b.type, type)
|
||||
assert_equal(b.points, points)
|
||||
b = IPC356_Outline.from_line('389BOARD_EDGE X100Y100 X20000Y20000 X40000 Y60000',
|
||||
FileSettings(units='inch'))
|
||||
assert_equal(b.type, 'BOARD_EDGE')
|
||||
assert_equal(b.points, points)
|
||||
assert b.type == type
|
||||
assert b.points == points
|
||||
b = IPC356_Outline.from_line(
|
||||
"389BOARD_EDGE X100Y100 X20000Y20000 X40000 Y60000",
|
||||
FileSettings(units="inch"),
|
||||
)
|
||||
assert b.type == "BOARD_EDGE"
|
||||
assert b.points == points
|
||||
|
||||
|
||||
def test_test_record():
|
||||
assert_raises(ValueError, IPC356_TestRecord.from_line,
|
||||
'P JOB', FileSettings())
|
||||
record_string = '317+5VDC VIA - D0150PA00X 006647Y 012900X0000 S3'
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units='inch'))
|
||||
assert_equal(r.feature_type, 'through-hole')
|
||||
assert_equal(r.net_name, '+5VDC')
|
||||
assert_equal(r.id, 'VIA')
|
||||
assert_almost_equal(r.hole_diameter, 0.015)
|
||||
assert_true(r.plated)
|
||||
assert_equal(r.access, 'both')
|
||||
assert_almost_equal(r.x_coord, 0.6647)
|
||||
assert_almost_equal(r.y_coord, 1.29)
|
||||
assert_equal(r.rect_x, 0.)
|
||||
assert_equal(r.soldermask_info, 'both')
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units='metric'))
|
||||
assert_almost_equal(r.hole_diameter, 0.15)
|
||||
assert_almost_equal(r.x_coord, 6.647)
|
||||
assert_almost_equal(r.y_coord, 12.9)
|
||||
assert_equal(r.rect_x, 0.)
|
||||
assert_equal(str(r), '<IPC-D-356 +5VDC Test Record: through-hole>')
|
||||
pytest.raises(ValueError, IPC356_TestRecord.from_line, "P JOB", FileSettings())
|
||||
record_string = (
|
||||
"317+5VDC VIA - D0150PA00X 006647Y 012900X0000 S3"
|
||||
)
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="inch"))
|
||||
assert r.feature_type == "through-hole"
|
||||
assert r.net_name == "+5VDC"
|
||||
assert r.id == "VIA"
|
||||
pytest.approx(r.hole_diameter, 0.015)
|
||||
assert r.plated
|
||||
assert r.access == "both"
|
||||
pytest.approx(r.x_coord, 0.6647)
|
||||
pytest.approx(r.y_coord, 1.29)
|
||||
assert r.rect_x == 0.0
|
||||
assert r.soldermask_info == "both"
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="metric"))
|
||||
pytest.approx(r.hole_diameter, 0.15)
|
||||
pytest.approx(r.x_coord, 6.647)
|
||||
pytest.approx(r.y_coord, 12.9)
|
||||
assert r.rect_x == 0.0
|
||||
assert str(r) == "<IPC-D-356 +5VDC Test Record: through-hole>"
|
||||
|
||||
record_string = '327+3.3VDC R40 -1 PA01X 032100Y 007124X0236Y0315R180 S0'
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units='inch'))
|
||||
assert_equal(r.feature_type, 'smt')
|
||||
assert_equal(r.net_name, '+3.3VDC')
|
||||
assert_equal(r.id, 'R40')
|
||||
assert_equal(r.pin, '1')
|
||||
assert_true(r.plated)
|
||||
assert_equal(r.access, 'top')
|
||||
assert_almost_equal(r.x_coord, 3.21)
|
||||
assert_almost_equal(r.y_coord, 0.7124)
|
||||
assert_almost_equal(r.rect_x, 0.0236)
|
||||
assert_almost_equal(r.rect_y, 0.0315)
|
||||
assert_equal(r.rect_rotation, 180)
|
||||
assert_equal(r.soldermask_info, 'none')
|
||||
r = IPC356_TestRecord.from_line(
|
||||
record_string, FileSettings(units='metric'))
|
||||
assert_almost_equal(r.x_coord, 32.1)
|
||||
assert_almost_equal(r.y_coord, 7.124)
|
||||
assert_almost_equal(r.rect_x, 0.236)
|
||||
assert_almost_equal(r.rect_y, 0.315)
|
||||
record_string = (
|
||||
"327+3.3VDC R40 -1 PA01X 032100Y 007124X0236Y0315R180 S0"
|
||||
)
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="inch"))
|
||||
assert r.feature_type == "smt"
|
||||
assert r.net_name == "+3.3VDC"
|
||||
assert r.id == "R40"
|
||||
assert r.pin == "1"
|
||||
assert r.plated
|
||||
assert r.access == "top"
|
||||
pytest.approx(r.x_coord, 3.21)
|
||||
pytest.approx(r.y_coord, 0.7124)
|
||||
pytest.approx(r.rect_x, 0.0236)
|
||||
pytest.approx(r.rect_y, 0.0315)
|
||||
assert r.rect_rotation == 180
|
||||
assert r.soldermask_info == "none"
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="metric"))
|
||||
pytest.approx(r.x_coord, 32.1)
|
||||
pytest.approx(r.y_coord, 7.124)
|
||||
pytest.approx(r.rect_x, 0.236)
|
||||
pytest.approx(r.rect_y, 0.315)
|
||||
|
||||
record_string = '317 J4 -M2 D0330PA00X 012447Y 008030X0000 S1'
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units='inch'))
|
||||
assert_equal(r.feature_type, 'through-hole')
|
||||
assert_equal(r.id, 'J4')
|
||||
assert_equal(r.pin, 'M2')
|
||||
assert_almost_equal(r.hole_diameter, 0.033)
|
||||
assert_true(r.plated)
|
||||
assert_equal(r.access, 'both')
|
||||
assert_almost_equal(r.x_coord, 1.2447)
|
||||
assert_almost_equal(r.y_coord, 0.8030)
|
||||
assert_almost_equal(r.rect_x, 0.)
|
||||
assert_equal(r.soldermask_info, 'primary side')
|
||||
record_string = (
|
||||
"317 J4 -M2 D0330PA00X 012447Y 008030X0000 S1"
|
||||
)
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="inch"))
|
||||
assert r.feature_type == "through-hole"
|
||||
assert r.id == "J4"
|
||||
assert r.pin == "M2"
|
||||
pytest.approx(r.hole_diameter, 0.033)
|
||||
assert r.plated
|
||||
assert r.access == "both"
|
||||
pytest.approx(r.x_coord, 1.2447)
|
||||
pytest.approx(r.y_coord, 0.8030)
|
||||
pytest.approx(r.rect_x, 0.0)
|
||||
assert r.soldermask_info == "primary side"
|
||||
|
||||
record_string = '317SCL COMMUNICATION-1 D 40PA00X 34000Y 20000X 600Y1200R270 '
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units='inch'))
|
||||
assert_equal(r.feature_type, 'through-hole')
|
||||
assert_equal(r.net_name, 'SCL')
|
||||
assert_equal(r.id, 'COMMUNICATION')
|
||||
assert_equal(r.pin, '1')
|
||||
assert_almost_equal(r.hole_diameter, 0.004)
|
||||
assert_true(r.plated)
|
||||
assert_almost_equal(r.x_coord, 3.4)
|
||||
assert_almost_equal(r.y_coord, 2.0)
|
||||
record_string = "317SCL COMMUNICATION-1 D 40PA00X 34000Y 20000X 600Y1200R270 "
|
||||
r = IPC356_TestRecord.from_line(record_string, FileSettings(units="inch"))
|
||||
assert r.feature_type == "through-hole"
|
||||
assert r.net_name == "SCL"
|
||||
assert r.id == "COMMUNICATION"
|
||||
assert r.pin == "1"
|
||||
pytest.approx(r.hole_diameter, 0.004)
|
||||
assert r.plated
|
||||
pytest.approx(r.x_coord, 3.4)
|
||||
pytest.approx(r.y_coord, 2.0)
|
||||
|
|
|
|||
|
|
@ -18,128 +18,141 @@
|
|||
|
||||
import os
|
||||
|
||||
from .tests import *
|
||||
from ..layers import *
|
||||
from ..common import read
|
||||
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/ncdrill.DRD')
|
||||
NETLIST_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/ipc-d-356.ipc')
|
||||
COPPER_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/top_copper.GTL')
|
||||
NCDRILL_FILE = os.path.join(os.path.dirname(__file__), "resources/ncdrill.DRD")
|
||||
NETLIST_FILE = os.path.join(os.path.dirname(__file__), "resources/ipc-d-356.ipc")
|
||||
COPPER_FILE = os.path.join(os.path.dirname(__file__), "resources/top_copper.GTL")
|
||||
|
||||
|
||||
def test_guess_layer_class():
|
||||
""" Test layer type inferred correctly from filename
|
||||
"""
|
||||
|
||||
# Add any specific test cases here (filename, layer_class)
|
||||
test_vectors = [(None, 'unknown'), ('NCDRILL.TXT', 'unknown'),
|
||||
('example_board.gtl', 'top'),
|
||||
('exampmle_board.sst', 'topsilk'),
|
||||
('ipc-d-356.ipc', 'ipc_netlist'), ]
|
||||
test_vectors = [
|
||||
(None, "unknown"),
|
||||
("NCDRILL.TXT", "unknown"),
|
||||
("example_board.gtl", "top"),
|
||||
("exampmle_board.sst", "topsilk"),
|
||||
("ipc-d-356.ipc", "ipc_netlist"),
|
||||
]
|
||||
|
||||
for hint in hints:
|
||||
for ext in hint.ext:
|
||||
assert_equal(hint.layer, guess_layer_class('board.{}'.format(ext)))
|
||||
assert hint.layer == guess_layer_class("board.{}".format(ext))
|
||||
for name in hint.name:
|
||||
assert_equal(hint.layer, guess_layer_class('{}.pho'.format(name)))
|
||||
assert hint.layer == guess_layer_class("{}.pho".format(name))
|
||||
|
||||
for filename, layer_class in test_vectors:
|
||||
assert_equal(layer_class, guess_layer_class(filename))
|
||||
assert layer_class == guess_layer_class(filename)
|
||||
|
||||
|
||||
def test_guess_layer_class_regex():
|
||||
""" Test regular expressions for layer matching
|
||||
"""
|
||||
|
||||
# Add any specific test case (filename, layer_class)
|
||||
test_vectors = [('test - top copper.gbr', 'top'),
|
||||
('test - copper top.gbr', 'top'), ]
|
||||
test_vectors = [("test - top copper.gbr", "top"), ("test - copper top.gbr", "top")]
|
||||
|
||||
# Add custom regular expressions
|
||||
layer_hints = [
|
||||
Hint(layer='top',
|
||||
ext=[],
|
||||
name=[],
|
||||
regex=r'(.*)(\scopper top|\stop copper).gbr',
|
||||
content=[]
|
||||
),
|
||||
Hint(
|
||||
layer="top",
|
||||
ext=[],
|
||||
name=[],
|
||||
regex=r"(.*)(\scopper top|\stop copper).gbr",
|
||||
content=[],
|
||||
)
|
||||
]
|
||||
hints.extend(layer_hints)
|
||||
|
||||
for filename, layer_class in test_vectors:
|
||||
assert_equal(layer_class, guess_layer_class(filename))
|
||||
assert layer_class == guess_layer_class(filename)
|
||||
|
||||
|
||||
def test_guess_layer_class_by_content():
|
||||
""" Test layer class by checking content
|
||||
"""
|
||||
|
||||
expected_layer_class = 'bottom'
|
||||
filename = os.path.join(os.path.dirname(__file__),
|
||||
'resources/example_guess_by_content.g0')
|
||||
expected_layer_class = "bottom"
|
||||
filename = os.path.join(
|
||||
os.path.dirname(__file__), "resources/example_guess_by_content.g0"
|
||||
)
|
||||
|
||||
layer_hints = [
|
||||
Hint(layer='bottom',
|
||||
ext=[],
|
||||
name=[],
|
||||
regex='',
|
||||
content=['G04 Layer name: Bottom']
|
||||
)
|
||||
Hint(
|
||||
layer="bottom",
|
||||
ext=[],
|
||||
name=[],
|
||||
regex="",
|
||||
content=["G04 Layer name: Bottom"],
|
||||
)
|
||||
]
|
||||
hints.extend(layer_hints)
|
||||
|
||||
assert_equal(expected_layer_class, guess_layer_class_by_content(filename))
|
||||
assert expected_layer_class == guess_layer_class_by_content(filename)
|
||||
|
||||
|
||||
def test_sort_layers():
|
||||
""" Test layer ordering
|
||||
"""
|
||||
layers = [
|
||||
PCBLayer(layer_class='drawing'),
|
||||
PCBLayer(layer_class='drill'),
|
||||
PCBLayer(layer_class='bottompaste'),
|
||||
PCBLayer(layer_class='bottomsilk'),
|
||||
PCBLayer(layer_class='bottommask'),
|
||||
PCBLayer(layer_class='bottom'),
|
||||
PCBLayer(layer_class='internal'),
|
||||
PCBLayer(layer_class='top'),
|
||||
PCBLayer(layer_class='topmask'),
|
||||
PCBLayer(layer_class='topsilk'),
|
||||
PCBLayer(layer_class='toppaste'),
|
||||
PCBLayer(layer_class='outline'),
|
||||
PCBLayer(layer_class="drawing"),
|
||||
PCBLayer(layer_class="drill"),
|
||||
PCBLayer(layer_class="bottompaste"),
|
||||
PCBLayer(layer_class="bottomsilk"),
|
||||
PCBLayer(layer_class="bottommask"),
|
||||
PCBLayer(layer_class="bottom"),
|
||||
PCBLayer(layer_class="internal"),
|
||||
PCBLayer(layer_class="top"),
|
||||
PCBLayer(layer_class="topmask"),
|
||||
PCBLayer(layer_class="topsilk"),
|
||||
PCBLayer(layer_class="toppaste"),
|
||||
PCBLayer(layer_class="outline"),
|
||||
]
|
||||
|
||||
layer_order = ['outline', 'toppaste', 'topsilk', 'topmask', 'top',
|
||||
'internal', 'bottom', 'bottommask', 'bottomsilk',
|
||||
'bottompaste', 'drill', 'drawing']
|
||||
layer_order = [
|
||||
"outline",
|
||||
"toppaste",
|
||||
"topsilk",
|
||||
"topmask",
|
||||
"top",
|
||||
"internal",
|
||||
"bottom",
|
||||
"bottommask",
|
||||
"bottomsilk",
|
||||
"bottompaste",
|
||||
"drill",
|
||||
"drawing",
|
||||
]
|
||||
bottom_order = list(reversed(layer_order[:10])) + layer_order[10:]
|
||||
assert_equal([l.layer_class for l in sort_layers(layers)], layer_order)
|
||||
assert_equal([l.layer_class for l in sort_layers(layers, from_top=False)],
|
||||
bottom_order)
|
||||
assert [l.layer_class for l in sort_layers(layers)] == layer_order
|
||||
assert [l.layer_class for l in sort_layers(layers, from_top=False)] == bottom_order
|
||||
|
||||
|
||||
def test_PCBLayer_from_file():
|
||||
layer = PCBLayer.from_cam(read(COPPER_FILE))
|
||||
assert_true(isinstance(layer, PCBLayer))
|
||||
assert isinstance(layer, PCBLayer)
|
||||
layer = PCBLayer.from_cam(read(NCDRILL_FILE))
|
||||
assert_true(isinstance(layer, DrillLayer))
|
||||
assert isinstance(layer, DrillLayer)
|
||||
layer = PCBLayer.from_cam(read(NETLIST_FILE))
|
||||
assert_true(isinstance(layer, PCBLayer))
|
||||
assert_equal(layer.layer_class, 'ipc_netlist')
|
||||
assert isinstance(layer, PCBLayer)
|
||||
assert layer.layer_class == "ipc_netlist"
|
||||
|
||||
|
||||
def test_PCBLayer_bounds():
|
||||
source = read(COPPER_FILE)
|
||||
layer = PCBLayer.from_cam(source)
|
||||
assert_equal(source.bounds, layer.bounds)
|
||||
assert source.bounds == layer.bounds
|
||||
|
||||
|
||||
def test_DrillLayer_from_cam():
|
||||
no_exceptions = True
|
||||
try:
|
||||
layer = DrillLayer.from_cam(read(NCDRILL_FILE))
|
||||
assert_true(isinstance(layer, DrillLayer))
|
||||
assert isinstance(layer, DrillLayer)
|
||||
except:
|
||||
no_exceptions = False
|
||||
assert_true(no_exceptions)
|
||||
assert no_exceptions
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,53 +3,53 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from ..rs274x import read, GerberFile
|
||||
from .tests import *
|
||||
|
||||
|
||||
TOP_COPPER_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/top_copper.GTL')
|
||||
TOP_COPPER_FILE = os.path.join(os.path.dirname(__file__), "resources/top_copper.GTL")
|
||||
|
||||
MULTILINE_READ_FILE = os.path.join(os.path.dirname(__file__),
|
||||
'resources/multiline_read.ger')
|
||||
MULTILINE_READ_FILE = os.path.join(
|
||||
os.path.dirname(__file__), "resources/multiline_read.ger"
|
||||
)
|
||||
|
||||
|
||||
def test_read():
|
||||
top_copper = read(TOP_COPPER_FILE)
|
||||
assert(isinstance(top_copper, GerberFile))
|
||||
assert isinstance(top_copper, GerberFile)
|
||||
|
||||
|
||||
def test_multiline_read():
|
||||
multiline = read(MULTILINE_READ_FILE)
|
||||
assert(isinstance(multiline, GerberFile))
|
||||
assert_equal(10, len(multiline.statements))
|
||||
assert isinstance(multiline, GerberFile)
|
||||
assert 10 == len(multiline.statements)
|
||||
|
||||
|
||||
def test_comments_parameter():
|
||||
top_copper = read(TOP_COPPER_FILE)
|
||||
assert_equal(top_copper.comments[0], 'This is a comment,:')
|
||||
assert top_copper.comments[0] == "This is a comment,:"
|
||||
|
||||
|
||||
def test_size_parameter():
|
||||
top_copper = read(TOP_COPPER_FILE)
|
||||
size = top_copper.size
|
||||
assert_almost_equal(size[0], 2.256900, 6)
|
||||
assert_almost_equal(size[1], 1.500000, 6)
|
||||
pytest.approx(size[0], 2.256900, 6)
|
||||
pytest.approx(size[1], 1.500000, 6)
|
||||
|
||||
|
||||
def test_conversion():
|
||||
top_copper = read(TOP_COPPER_FILE)
|
||||
assert_equal(top_copper.units, 'inch')
|
||||
assert top_copper.units == "inch"
|
||||
top_copper_inch = read(TOP_COPPER_FILE)
|
||||
top_copper.to_metric()
|
||||
for statement in top_copper_inch.statements:
|
||||
statement.to_metric()
|
||||
for primitive in top_copper_inch.primitives:
|
||||
primitive.to_metric()
|
||||
assert_equal(top_copper.units, 'metric')
|
||||
assert top_copper.units == "metric"
|
||||
for i, m in zip(top_copper.statements, top_copper_inch.statements):
|
||||
assert_equal(i, m)
|
||||
assert i == m
|
||||
|
||||
for i, m in zip(top_copper.primitives, top_copper_inch.primitives):
|
||||
assert_equal(i, m)
|
||||
assert i == m
|
||||
|
|
|
|||
|
|
@ -7,62 +7,86 @@ import os
|
|||
|
||||
from ..render.rs274x_backend import Rs274xContext
|
||||
from ..rs274x import read
|
||||
from .tests import *
|
||||
|
||||
|
||||
def test_render_two_boxes():
|
||||
"""Umaco exapmle of two boxes"""
|
||||
_test_render('resources/example_two_square_boxes.gbr', 'golden/example_two_square_boxes.gbr')
|
||||
_test_render(
|
||||
"resources/example_two_square_boxes.gbr", "golden/example_two_square_boxes.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_single_quadrant():
|
||||
"""Umaco exapmle of a single quadrant arc"""
|
||||
|
||||
# TODO there is probably a bug here
|
||||
_test_render('resources/example_single_quadrant.gbr', 'golden/example_single_quadrant.gbr')
|
||||
_test_render(
|
||||
"resources/example_single_quadrant.gbr", "golden/example_single_quadrant.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_simple_contour():
|
||||
"""Umaco exapmle of a simple arrow-shaped contour"""
|
||||
_test_render('resources/example_simple_contour.gbr', 'golden/example_simple_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_simple_contour.gbr", "golden/example_simple_contour.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_single_contour_1():
|
||||
"""Umaco example of a single contour
|
||||
|
||||
The resulting image for this test is used by other tests because they must generate the same output."""
|
||||
_test_render('resources/example_single_contour_1.gbr', 'golden/example_single_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_single_contour_1.gbr", "golden/example_single_contour.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_single_contour_2():
|
||||
"""Umaco exapmle of a single contour, alternate contour end order
|
||||
|
||||
The resulting image for this test is used by other tests because they must generate the same output."""
|
||||
_test_render('resources/example_single_contour_2.gbr', 'golden/example_single_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_single_contour_2.gbr", "golden/example_single_contour.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_single_contour_3():
|
||||
"""Umaco exapmle of a single contour with extra line"""
|
||||
_test_render('resources/example_single_contour_3.gbr', 'golden/example_single_contour_3.gbr')
|
||||
_test_render(
|
||||
"resources/example_single_contour_3.gbr", "golden/example_single_contour_3.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_not_overlapping_contour():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_not_overlapping_contour.gbr', 'golden/example_not_overlapping_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_not_overlapping_contour.gbr",
|
||||
"golden/example_not_overlapping_contour.gbr",
|
||||
)
|
||||
|
||||
|
||||
def _test_render_not_overlapping_touching():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_not_overlapping_touching.gbr', 'golden/example_not_overlapping_touching.gbr')
|
||||
_test_render(
|
||||
"resources/example_not_overlapping_touching.gbr",
|
||||
"golden/example_not_overlapping_touching.gbr",
|
||||
)
|
||||
|
||||
|
||||
def _test_render_overlapping_touching():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_overlapping_touching.gbr', 'golden/example_overlapping_touching.gbr')
|
||||
_test_render(
|
||||
"resources/example_overlapping_touching.gbr",
|
||||
"golden/example_overlapping_touching.gbr",
|
||||
)
|
||||
|
||||
|
||||
def _test_render_overlapping_contour():
|
||||
"""Umaco example of D02 staring a second contour"""
|
||||
_test_render('resources/example_overlapping_contour.gbr', 'golden/example_overlapping_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_overlapping_contour.gbr",
|
||||
"golden/example_overlapping_contour.gbr",
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_level_holes():
|
||||
|
|
@ -70,76 +94,96 @@ def _DISABLED_test_render_level_holes():
|
|||
|
||||
# TODO This is clearly rendering wrong. I'm temporarily checking this in because there are more
|
||||
# rendering fixes in the related repository that may resolve these.
|
||||
_test_render('resources/example_level_holes.gbr', 'golden/example_overlapping_contour.gbr')
|
||||
_test_render(
|
||||
"resources/example_level_holes.gbr", "golden/example_overlapping_contour.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _DISABLED_test_render_cutin():
|
||||
"""Umaco example of using a cutin"""
|
||||
|
||||
# TODO This is clearly rendering wrong.
|
||||
_test_render('resources/example_cutin.gbr', 'golden/example_cutin.gbr')
|
||||
_test_render("resources/example_cutin.gbr", "golden/example_cutin.gbr")
|
||||
|
||||
|
||||
def _test_render_fully_coincident():
|
||||
"""Umaco example of coincident lines rendering two contours"""
|
||||
|
||||
_test_render('resources/example_fully_coincident.gbr', 'golden/example_fully_coincident.gbr')
|
||||
_test_render(
|
||||
"resources/example_fully_coincident.gbr", "golden/example_fully_coincident.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_coincident_hole():
|
||||
"""Umaco example of coincident lines rendering a hole in the contour"""
|
||||
|
||||
_test_render('resources/example_coincident_hole.gbr', 'golden/example_coincident_hole.gbr')
|
||||
_test_render(
|
||||
"resources/example_coincident_hole.gbr", "golden/example_coincident_hole.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_cutin_multiple():
|
||||
"""Umaco example of a region with multiple cutins"""
|
||||
|
||||
_test_render('resources/example_cutin_multiple.gbr', 'golden/example_cutin_multiple.gbr')
|
||||
_test_render(
|
||||
"resources/example_cutin_multiple.gbr", "golden/example_cutin_multiple.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_flash_circle():
|
||||
"""Umaco example a simple circular flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_circle.gbr', 'golden/example_flash_circle.gbr')
|
||||
_test_render(
|
||||
"resources/example_flash_circle.gbr", "golden/example_flash_circle.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_flash_rectangle():
|
||||
"""Umaco example a simple rectangular flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_rectangle.gbr', 'golden/example_flash_rectangle.gbr')
|
||||
_test_render(
|
||||
"resources/example_flash_rectangle.gbr", "golden/example_flash_rectangle.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_flash_obround():
|
||||
"""Umaco example a simple obround flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_obround.gbr', 'golden/example_flash_obround.gbr')
|
||||
_test_render(
|
||||
"resources/example_flash_obround.gbr", "golden/example_flash_obround.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_flash_polygon():
|
||||
"""Umaco example a simple polygon flash with and without a hole"""
|
||||
|
||||
_test_render('resources/example_flash_polygon.gbr', 'golden/example_flash_polygon.gbr')
|
||||
_test_render(
|
||||
"resources/example_flash_polygon.gbr", "golden/example_flash_polygon.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_holes_dont_clear():
|
||||
"""Umaco example that an aperture with a hole does not clear the area"""
|
||||
|
||||
_test_render('resources/example_holes_dont_clear.gbr', 'golden/example_holes_dont_clear.gbr')
|
||||
_test_render(
|
||||
"resources/example_holes_dont_clear.gbr", "golden/example_holes_dont_clear.gbr"
|
||||
)
|
||||
|
||||
|
||||
def _test_render_am_exposure_modifier():
|
||||
"""Umaco example that an aperture macro with a hole does not clear the area"""
|
||||
|
||||
_test_render('resources/example_am_exposure_modifier.gbr', 'golden/example_am_exposure_modifier.gbr')
|
||||
_test_render(
|
||||
"resources/example_am_exposure_modifier.gbr",
|
||||
"golden/example_am_exposure_modifier.gbr",
|
||||
)
|
||||
|
||||
|
||||
def _resolve_path(path):
|
||||
return os.path.join(os.path.dirname(__file__),
|
||||
path)
|
||||
return os.path.join(os.path.dirname(__file__), path)
|
||||
|
||||
|
||||
def _test_render(gerber_path, png_expected_path, create_output_path = None):
|
||||
def _test_render(gerber_path, png_expected_path, create_output_path=None):
|
||||
"""Render the gerber file and compare to the expected PNG output.
|
||||
|
||||
Parameters
|
||||
|
|
@ -168,18 +212,21 @@ def _test_render(gerber_path, png_expected_path, create_output_path = None):
|
|||
|
||||
# If we want to write the file bytes, do it now. This happens
|
||||
if create_output_path:
|
||||
with open(create_output_path, 'wb') as out_file:
|
||||
with open(create_output_path, "wb") as out_file:
|
||||
out_file.write(actual_contents.getvalue())
|
||||
# Creating the output is dangerous - it could overwrite the expected result.
|
||||
# So if we are creating the output, we make the test fail on purpose so you
|
||||
# won't forget to disable this
|
||||
assert_false(True, 'Test created the output %s. This needs to be disabled to make sure the test behaves correctly' % (create_output_path,))
|
||||
assert not True, (
|
||||
"Test created the output %s. This needs to be disabled to make sure the test behaves correctly"
|
||||
% (create_output_path,)
|
||||
)
|
||||
|
||||
# Read the expected PNG file
|
||||
|
||||
with open(png_expected_path, 'r') as expected_file:
|
||||
with open(png_expected_path, "r") as expected_file:
|
||||
expected_contents = expected_file.read()
|
||||
|
||||
assert_equal(expected_contents, actual_contents.getvalue())
|
||||
assert expected_contents == actual_contents.getvalue()
|
||||
|
||||
return gerber
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
from .tests import assert_equal, assert_raises
|
||||
import pytest
|
||||
from ..utils import *
|
||||
|
||||
|
||||
|
|
@ -14,60 +14,99 @@ def test_zero_suppression():
|
|||
fmt = (2, 5)
|
||||
|
||||
# Test leading zero suppression
|
||||
zero_suppression = 'leading'
|
||||
test_cases = [('1', 0.00001), ('10', 0.0001), ('100', 0.001),
|
||||
('1000', 0.01), ('10000', 0.1), ('100000', 1.0),
|
||||
('1000000', 10.0), ('-1', -0.00001), ('-10', -0.0001),
|
||||
('-100', -0.001), ('-1000', -0.01), ('-10000', -0.1),
|
||||
('-100000', -1.0), ('-1000000', -10.0),
|
||||
('0', 0.0)]
|
||||
zero_suppression = "leading"
|
||||
test_cases = [
|
||||
("1", 0.00001),
|
||||
("10", 0.0001),
|
||||
("100", 0.001),
|
||||
("1000", 0.01),
|
||||
("10000", 0.1),
|
||||
("100000", 1.0),
|
||||
("1000000", 10.0),
|
||||
("-1", -0.00001),
|
||||
("-10", -0.0001),
|
||||
("-100", -0.001),
|
||||
("-1000", -0.01),
|
||||
("-10000", -0.1),
|
||||
("-100000", -1.0),
|
||||
("-1000000", -10.0),
|
||||
("0", 0.0),
|
||||
]
|
||||
for string, value in test_cases:
|
||||
assert_equal(value, parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert_equal(string, write_gerber_value(value, fmt, zero_suppression))
|
||||
assert value == parse_gerber_value(string, fmt, zero_suppression)
|
||||
assert string == write_gerber_value(value, fmt, zero_suppression)
|
||||
|
||||
# Test trailing zero suppression
|
||||
zero_suppression = 'trailing'
|
||||
test_cases = [('1', 10.0), ('01', 1.0), ('001', 0.1), ('0001', 0.01),
|
||||
('00001', 0.001), ('000001', 0.0001),
|
||||
('0000001', 0.00001), ('-1', -10.0), ('-01', -1.0),
|
||||
('-001', -0.1), ('-0001', -0.01), ('-00001', -0.001),
|
||||
('-000001', -0.0001), ('-0000001', -0.00001),
|
||||
('0', 0.0)]
|
||||
zero_suppression = "trailing"
|
||||
test_cases = [
|
||||
("1", 10.0),
|
||||
("01", 1.0),
|
||||
("001", 0.1),
|
||||
("0001", 0.01),
|
||||
("00001", 0.001),
|
||||
("000001", 0.0001),
|
||||
("0000001", 0.00001),
|
||||
("-1", -10.0),
|
||||
("-01", -1.0),
|
||||
("-001", -0.1),
|
||||
("-0001", -0.01),
|
||||
("-00001", -0.001),
|
||||
("-000001", -0.0001),
|
||||
("-0000001", -0.00001),
|
||||
("0", 0.0),
|
||||
]
|
||||
for string, value in test_cases:
|
||||
assert_equal(value, parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert_equal(string, write_gerber_value(value, fmt, zero_suppression))
|
||||
assert value == parse_gerber_value(string, fmt, zero_suppression)
|
||||
assert string == write_gerber_value(value, fmt, zero_suppression)
|
||||
|
||||
assert_equal(write_gerber_value(0.000000001, fmt, 'leading'), '0')
|
||||
assert_equal(write_gerber_value(0.000000001, fmt, 'trailing'), '0')
|
||||
assert write_gerber_value(0.000000001, fmt, "leading") == "0"
|
||||
assert write_gerber_value(0.000000001, fmt, "trailing") == "0"
|
||||
|
||||
|
||||
def test_format():
|
||||
""" Test gerber value parser and writer handle format correctly
|
||||
"""
|
||||
zero_suppression = 'leading'
|
||||
test_cases = [((2, 7), '1', 0.0000001), ((2, 6), '1', 0.000001),
|
||||
((2, 5), '1', 0.00001), ((2, 4), '1', 0.0001),
|
||||
((2, 3), '1', 0.001), ((2, 2), '1', 0.01),
|
||||
((2, 1), '1', 0.1), ((2, 7), '-1', -0.0000001),
|
||||
((2, 6), '-1', -0.000001), ((2, 5), '-1', -0.00001),
|
||||
((2, 4), '-1', -0.0001), ((2, 3), '-1', -0.001),
|
||||
((2, 2), '-1', -0.01), ((2, 1), '-1', -0.1),
|
||||
((2, 6), '0', 0)]
|
||||
zero_suppression = "leading"
|
||||
test_cases = [
|
||||
((2, 7), "1", 0.0000001),
|
||||
((2, 6), "1", 0.000001),
|
||||
((2, 5), "1", 0.00001),
|
||||
((2, 4), "1", 0.0001),
|
||||
((2, 3), "1", 0.001),
|
||||
((2, 2), "1", 0.01),
|
||||
((2, 1), "1", 0.1),
|
||||
((2, 7), "-1", -0.0000001),
|
||||
((2, 6), "-1", -0.000001),
|
||||
((2, 5), "-1", -0.00001),
|
||||
((2, 4), "-1", -0.0001),
|
||||
((2, 3), "-1", -0.001),
|
||||
((2, 2), "-1", -0.01),
|
||||
((2, 1), "-1", -0.1),
|
||||
((2, 6), "0", 0),
|
||||
]
|
||||
for fmt, string, value in test_cases:
|
||||
assert_equal(value, parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert_equal(string, write_gerber_value(value, fmt, zero_suppression))
|
||||
assert value == parse_gerber_value(string, fmt, zero_suppression)
|
||||
assert string == write_gerber_value(value, fmt, zero_suppression)
|
||||
|
||||
zero_suppression = 'trailing'
|
||||
test_cases = [((6, 5), '1', 100000.0), ((5, 5), '1', 10000.0),
|
||||
((4, 5), '1', 1000.0), ((3, 5), '1', 100.0),
|
||||
((2, 5), '1', 10.0), ((1, 5), '1', 1.0),
|
||||
((6, 5), '-1', -100000.0), ((5, 5), '-1', -10000.0),
|
||||
((4, 5), '-1', -1000.0), ((3, 5), '-1', -100.0),
|
||||
((2, 5), '-1', -10.0), ((1, 5), '-1', -1.0),
|
||||
((2, 5), '0', 0)]
|
||||
zero_suppression = "trailing"
|
||||
test_cases = [
|
||||
((6, 5), "1", 100000.0),
|
||||
((5, 5), "1", 10000.0),
|
||||
((4, 5), "1", 1000.0),
|
||||
((3, 5), "1", 100.0),
|
||||
((2, 5), "1", 10.0),
|
||||
((1, 5), "1", 1.0),
|
||||
((6, 5), "-1", -100000.0),
|
||||
((5, 5), "-1", -10000.0),
|
||||
((4, 5), "-1", -1000.0),
|
||||
((3, 5), "-1", -100.0),
|
||||
((2, 5), "-1", -10.0),
|
||||
((1, 5), "-1", -1.0),
|
||||
((2, 5), "0", 0),
|
||||
]
|
||||
for fmt, string, value in test_cases:
|
||||
assert_equal(value, parse_gerber_value(string, fmt, zero_suppression))
|
||||
assert_equal(string, write_gerber_value(value, fmt, zero_suppression))
|
||||
assert value == parse_gerber_value(string, fmt, zero_suppression)
|
||||
assert string == write_gerber_value(value, fmt, zero_suppression)
|
||||
|
||||
|
||||
def test_decimal_truncation():
|
||||
|
|
@ -76,54 +115,53 @@ def test_decimal_truncation():
|
|||
value = 1.123456789
|
||||
for x in range(10):
|
||||
result = decimal_string(value, precision=x)
|
||||
calculated = '1.' + ''.join(str(y) for y in range(1, x + 1))
|
||||
assert_equal(result, calculated)
|
||||
calculated = "1." + "".join(str(y) for y in range(1, x + 1))
|
||||
assert result == calculated
|
||||
|
||||
|
||||
def test_decimal_padding():
|
||||
""" Test decimal_string padding
|
||||
"""
|
||||
value = 1.123
|
||||
assert_equal(decimal_string(value, precision=3, padding=True), '1.123')
|
||||
assert_equal(decimal_string(value, precision=4, padding=True), '1.1230')
|
||||
assert_equal(decimal_string(value, precision=5, padding=True), '1.12300')
|
||||
assert_equal(decimal_string(value, precision=6, padding=True), '1.123000')
|
||||
assert_equal(decimal_string(0, precision=6, padding=True), '0.000000')
|
||||
assert decimal_string(value, precision=3, padding=True) == "1.123"
|
||||
assert decimal_string(value, precision=4, padding=True) == "1.1230"
|
||||
assert decimal_string(value, precision=5, padding=True) == "1.12300"
|
||||
assert decimal_string(value, precision=6, padding=True) == "1.123000"
|
||||
assert decimal_string(0, precision=6, padding=True) == "0.000000"
|
||||
|
||||
|
||||
def test_parse_format_validation():
|
||||
""" Test parse_gerber_value() format validation
|
||||
"""
|
||||
assert_raises(ValueError, parse_gerber_value, '00001111', (7, 5))
|
||||
assert_raises(ValueError, parse_gerber_value, '00001111', (5, 8))
|
||||
assert_raises(ValueError, parse_gerber_value, '00001111', (13, 1))
|
||||
pytest.raises(ValueError, parse_gerber_value, "00001111", (7, 5))
|
||||
pytest.raises(ValueError, parse_gerber_value, "00001111", (5, 8))
|
||||
pytest.raises(ValueError, parse_gerber_value, "00001111", (13, 1))
|
||||
|
||||
|
||||
def test_write_format_validation():
|
||||
""" Test write_gerber_value() format validation
|
||||
"""
|
||||
assert_raises(ValueError, write_gerber_value, 69.0, (7, 5))
|
||||
assert_raises(ValueError, write_gerber_value, 69.0, (5, 8))
|
||||
assert_raises(ValueError, write_gerber_value, 69.0, (13, 1))
|
||||
pytest.raises(ValueError, write_gerber_value, 69.0, (7, 5))
|
||||
pytest.raises(ValueError, write_gerber_value, 69.0, (5, 8))
|
||||
pytest.raises(ValueError, write_gerber_value, 69.0, (13, 1))
|
||||
|
||||
|
||||
def test_detect_format_with_short_file():
|
||||
""" Verify file format detection works with short files
|
||||
"""
|
||||
assert_equal('unknown', detect_file_format('gerber/tests/__init__.py'))
|
||||
assert "unknown" == detect_file_format("gerber/tests/__init__.py")
|
||||
|
||||
|
||||
def test_validate_coordinates():
|
||||
assert_raises(TypeError, validate_coordinates, 3)
|
||||
assert_raises(TypeError, validate_coordinates, 3.1)
|
||||
assert_raises(TypeError, validate_coordinates, '14')
|
||||
assert_raises(TypeError, validate_coordinates, (0,))
|
||||
assert_raises(TypeError, validate_coordinates, (0, 1, 2))
|
||||
assert_raises(TypeError, validate_coordinates, (0, 'string'))
|
||||
pytest.raises(TypeError, validate_coordinates, 3)
|
||||
pytest.raises(TypeError, validate_coordinates, 3.1)
|
||||
pytest.raises(TypeError, validate_coordinates, "14")
|
||||
pytest.raises(TypeError, validate_coordinates, (0,))
|
||||
pytest.raises(TypeError, validate_coordinates, (0, 1, 2))
|
||||
pytest.raises(TypeError, validate_coordinates, (0, "string"))
|
||||
|
||||
|
||||
def test_convex_hull():
|
||||
points = [(0, 0), (1, 0), (1, 1), (0.5, 0.5), (0, 1), (0, 0)]
|
||||
expected = [(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]
|
||||
assert_equal(set(convex_hull(points)), set(expected))
|
||||
|
||||
assert set(convex_hull(points)) == set(expected)
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Author: Hamilton Kibbe <ham@hamiltonkib.be>
|
||||
|
||||
from nose.tools import assert_in
|
||||
from nose.tools import assert_not_in
|
||||
from nose.tools import assert_equal
|
||||
from nose.tools import assert_not_equal
|
||||
from nose.tools import assert_almost_equal
|
||||
from nose.tools import assert_true
|
||||
from nose.tools import assert_false
|
||||
from nose.tools import assert_raises
|
||||
from nose.tools import raises
|
||||
from nose import with_setup
|
||||
|
||||
__all__ = ['assert_in', 'assert_not_in', 'assert_equal', 'assert_not_equal',
|
||||
'assert_almost_equal', 'assert_array_almost_equal', 'assert_true',
|
||||
'assert_false', 'assert_raises', 'raises', 'with_setup']
|
||||
|
||||
|
||||
def assert_array_almost_equal(arr1, arr2, decimal=6):
|
||||
assert_equal(len(arr1), len(arr2))
|
||||
for i in range(len(arr1)):
|
||||
assert_almost_equal(arr1[i], arr2[i], decimal)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
# install base requirements
|
||||
-r requirements.txt
|
||||
|
||||
coverage==4.5.4
|
||||
nose==1.3.7
|
||||
pytest==4.6.6
|
||||
pytest-cov==2.8.1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue