pygcode/tests/test_gcodes.py
2017-07-06 01:04:37 +10:00

100 lines
4.5 KiB
Python

import sys
import os
import inspect
import re
import unittest
# Units Under Test
_this_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
sys.path.insert(0, os.path.join(_this_path, '..'))
from pygcode import gcodes
from pygcode import words
class TestGCodeWordMapping(unittest.TestCase):
def test_word_map_integrity(self):
gcodes.build_maps()
for (word_maches, fn_class) in gcodes._gcode_function_list:
for (word, key_class) in gcodes._gcode_word_map.items():
# Verify that no mapped word will yield a True result
# from any of the 'word_maches' functions
self.assertFalse(
word_maches(word),
"conflict with %s and %s" % (fn_class, key_class)
)
class TestGCodeModalGroups(unittest.TestCase):
def test_modal_groups(self):
# Modal groups taken (and slightly modified) from LinuxCNC documentation:
# link: http://linuxcnc.org/docs/html/gcode/overview.html#_modal_groups
table_rows = ''
# Table 5. G-Code Modal Groups
# MODAL GROUP MEANING MEMBER WORDS
table_rows += '''
Non-modal codes (Group 0) G4,G10,G28,G30,G53,G92,G92.1,G92.2,G92.3
Motion (Group 1) G0,G1,G2,G3,G33,G38.2,G38.3,G38.4
Motion (Group 1) G38.5,G73,G76,G80,G81,G82,G83,G85,G89
Plane selection (Group 2) G17, G18, G19, G17.1, G18.1, G19.1
Distance Mode (Group 3) G90, G91
Arc IJK Distance Mode (Group 4) G90.1, G91.1
Feed Rate Mode (Group 5) G93, G94, G95
Units (Group 6) G20, G21
Cutter Diameter Compensation (Group 7) G40, G41, G42, G41.1, G42.1
Tool Length Offset (Group 8) G43, G43.1, G49
Canned Cycles Return Mode (Group 10) G98
Coordinate System (Group 12) G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3
Control Mode (Group 13) G61, G61.1, G64
Spindle Speed Mode (Group 14) G96, G97
Lathe Diameter Mode (Group 15) G7,G8
'''
# Table 6. M-Code Modal Groups
# MODAL GROUP MEANING MEMBER WORDS
table_rows += '''
Stopping (Group 4) M0, M1, M2, M30, M60
Spindle (Group 7) M3, M4, M5
Coolant (Group 8) M7, M8, M9
Override Switches (Group 9) M48, M49
'''
for row in table_rows.split('\n'):
match = re.search(r'^\s*(?P<title>.*)\s*\(Group (?P<group>\d+)\)\s*(?P<words>.*)$', row, re.I)
if match:
for word_str in re.split(r'\s*,\s*', match.group('words')):
word = list(words.iter_words(word_str))[0]
gcode_class = gcodes.word_gcode_class(word)
# GCode class found for each word in the table
self.assertIsNotNone(gcode_class)
# GCode's modal group equals that defined in the table
expected_group = int(match.group('group'))
if expected_group == 0:
self.assertIsNone(
gcode_class.modal_group,
"%s modal_group: %s is not None" % (gcode_class, gcode_class.modal_group)
)
else:
self.assertEqual(
gcode_class.modal_group, expected_group,
"%s != %s (%r)" % (gcode_class.modal_group, expected_group, word)
)
class TestWordsToGCodes(unittest.TestCase):
def test_stuff(self): # FIXME: function name
line = 'G1 X82.6892 Y-38.6339 F1500'
word_list = list(words.iter_words(line))
result = gcodes.words_to_gcodes(word_list)
# result form
self.assertIsInstance(result, tuple)
self.assertEqual(len(result), 2)
# result content
(gcode_list, unused_words) = result
self.assertEqual(len(gcode_list), 2)
self.assertEqual(unused_words, [])
# Parsed GCodes
# G1
self.assertEqual(gcode_list[0].word, words.Word('G', 1))
self.assertEqual(gcode_list[0].X, 82.6892)
self.assertEqual(gcode_list[0].Y, -38.6339)
# F1500
self.assertEqual(gcode_list[1].word, words.Word('F', 1500))