FreeCAD

Форк
0
/
TestRefactoredTestPost.py 
526 строк · 21.5 Кб
1
# -*- coding: utf-8 -*-
2
# ***************************************************************************
3
# *   Copyright (c) 2022 sliptonic <shopinthewoods@gmail.com>               *
4
# *   Copyright (c) 2022-2023 Larry Woestman <LarryWoestman2@gmail.com>     *
5
# *                                                                         *
6
# *   This program is free software; you can redistribute it and/or modify  *
7
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
8
# *   as published by the Free Software Foundation; either version 2 of     *
9
# *   the License, or (at your option) any later version.                   *
10
# *   for detail see the LICENCE text file.                                 *
11
# *                                                                         *
12
# *   This program is distributed in the hope that it will be useful,       *
13
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
# *   GNU Library General Public License for more details.                  *
16
# *                                                                         *
17
# *   You should have received a copy of the GNU Library General Public     *
18
# *   License along with this program; if not, write to the Free Software   *
19
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
# *   USA                                                                   *
21
# *                                                                         *
22
# ***************************************************************************
23

24
import FreeCAD
25

26
import Path
27
import Tests.PathTestUtils as PathTestUtils
28
from Path.Post.scripts import refactored_test_post as postprocessor
29

30

31
Path.Log.setLevel(Path.Log.Level.DEBUG, Path.Log.thisModule())
32
Path.Log.trackModule(Path.Log.thisModule())
33

34

35
class TestRefactoredTestPost(PathTestUtils.PathTestBase):
36
    @classmethod
37
    def setUpClass(cls):
38
        """setUpClass()...
39

40
        This method is called upon instantiation of this test class.  Add code
41
        and objects here that are needed for the duration of the test() methods
42
        in this class.  In other words, set up the 'global' test environment
43
        here; use the `setUp()` method to set up a 'local' test environment.
44
        This method does not have access to the class `self` reference, but it
45
        is able to call static methods within this same class.
46
        """
47
        # Open existing FreeCAD document with test geometry
48
        FreeCAD.newDocument("Unnamed")
49

50
    @classmethod
51
    def tearDownClass(cls):
52
        """tearDownClass()...
53

54
        This method is called prior to destruction of this test class.  Add
55
        code and objects here that cleanup the test environment after the
56
        test() methods in this class have been executed.  This method does
57
        not have access to the class `self` reference.  This method is able
58
        to call static methods within this same class.
59
        """
60
        # Close geometry document without saving
61
        FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name)
62

63
    # Setup and tear down methods called before and after each unit test
64

65
    def setUp(self):
66
        """setUp()...
67

68
        This method is called prior to each `test()` method.  Add code and
69
        objects here that are needed for multiple `test()` methods.
70
        """
71
        self.maxDiff = None
72
        self.doc = FreeCAD.ActiveDocument
73
        self.con = FreeCAD.Console
74
        self.docobj = FreeCAD.ActiveDocument.addObject("Path::Feature", "testpath")
75
        #
76
        # Re-initialize all of the values before doing a test.
77
        #
78
        postprocessor.UNITS = "G21"
79
        postprocessor.init_values(postprocessor.global_values)
80

81
    def tearDown(self):
82
        """tearDown()...
83

84
        This method is called after each test() method. Add cleanup instructions here.
85
        Such cleanup instructions will likely undo those in the setUp() method.
86
        """
87
        FreeCAD.ActiveDocument.removeObject("testpath")
88

89
    def single_compare(self, path, expected, args, debug=False):
90
        """Perform a test with a single comparison."""
91
        nl = "\n"
92
        self.docobj.Path = Path.Path(path)
93
        postables = [self.docobj]
94
        gcode = postprocessor.export(postables, "-", args)
95
        if debug:
96
            print(f"--------{nl}{gcode}--------{nl}")
97
        self.assertEqual(gcode, expected)
98

99
    def compare_third_line(self, path_string, expected, args, debug=False):
100
        """Perform a test with a single comparison to the third line of the output."""
101
        nl = "\n"
102
        if path_string:
103
            self.docobj.Path = Path.Path([Path.Command(path_string)])
104
        else:
105
            self.docobj.Path = Path.Path([])
106
        postables = [self.docobj]
107
        gcode = postprocessor.export(postables, "-", args)
108
        if debug:
109
            print(f"--------{nl}{gcode}--------{nl}")
110
        self.assertEqual(gcode.splitlines()[2], expected)
111

112
    #############################################################################
113
    #
114
    # The tests are organized into groups:
115
    #
116
    #   00000 - 00099  tests that don't fit any other category
117
    #   00100 - 00999  tests for all of the various arguments/options
118
    #   01000 - 01999  tests for the various G codes at 1000 + 10 * g_code_value
119
    #   02000 - 02999  tests for the various M codes at 2000 + 10 * m_code_value
120
    #
121
    #############################################################################
122

123
    def test00100(self):
124
        """Test axis modal.
125

126
        Suppress the axis coordinate if the same as previous
127
        """
128
        c = Path.Command("G0 X10 Y20 Z30")
129
        c1 = Path.Command("G0 X10 Y30 Z30")
130

131
        self.docobj.Path = Path.Path([c, c1])
132
        postables = [self.docobj]
133

134
        args = "--axis-modal"
135
        gcode = postprocessor.export(postables, "-", args)
136
        # print("--------\n" + gcode + "--------\n")
137
        self.assertEqual(gcode.splitlines()[3], "G0 Y30.000")
138

139
        args = "--no-axis-modal"
140
        gcode = postprocessor.export(postables, "-", args)
141
        # print("--------\n" + gcode + "--------\n")
142
        self.assertEqual(gcode.splitlines()[3], "G0 X10.000 Y30.000 Z30.000")
143

144
    #############################################################################
145

146
    def test00110(self):
147
        """Test axis-precision."""
148
        self.compare_third_line("G0 X10 Y20 Z30", "G0 X10.00 Y20.00 Z30.00", "--axis-precision=2")
149

150
    #############################################################################
151

152
    def test00120(self):
153
        """Test bcnc."""
154
        self.single_compare(
155
            [],
156
            """G90
157
G21
158
(Block-name: testpath)
159
(Block-expand: 0)
160
(Block-enable: 1)
161
(Block-name: post_amble)
162
(Block-expand: 0)
163
(Block-enable: 1)
164
""",
165
            "--bcnc",
166
        )
167
        self.single_compare(
168
            [],
169
            """G90
170
G21
171
""",
172
            "--no-bcnc",
173
        )
174

175
    #############################################################################
176

177
    def test00130(self):
178
        """Test comments."""
179
        c = Path.Command("(comment)")
180
        self.docobj.Path = Path.Path([c])
181
        postables = [self.docobj]
182
        args = "--comments"
183
        gcode = postprocessor.export(postables, "-", args)
184
        # print("--------\n" + gcode + "--------\n")
185
        self.assertEqual(gcode.splitlines()[4], "(comment)")
186

187
    #############################################################################
188

189
    def test00140(self):
190
        """Test feed-precision."""
191
        #
192
        c = Path.Command("G1 X10 Y20 Z30 F123.123456")
193

194
        self.docobj.Path = Path.Path([c])
195
        postables = [self.docobj]
196

197
        args = ""
198
        gcode = postprocessor.export(postables, "-", args)
199
        # print("--------\n" + gcode + "--------\n")
200
        # Note:  The "internal" F speed is in mm/s,
201
        #        while the output F speed is in mm/min.
202
        self.assertEqual(gcode.splitlines()[2], "G1 X10.000 Y20.000 Z30.000 F7387.407")
203

204
        args = "--feed-precision=2"
205
        gcode = postprocessor.export(postables, "-", args)
206
        # print("--------\n" + gcode + "--------\n")
207
        # Note:  The "internal" F speed is in mm/s,
208
        #        while the output F speed is in mm/min.
209
        self.assertEqual(gcode.splitlines()[2], "G1 X10.000 Y20.000 Z30.000 F7387.41")
210

211
    #############################################################################
212

213
    def test00150(self):
214
        """Test output with an empty path.
215

216
        Also tests the interactions between --comments and --header.
217
        """
218
        self.docobj.Path = Path.Path([])
219
        postables = [self.docobj]
220

221
        # Test generating with comments and header.
222
        # The header contains a time stamp that messes up unit testing.
223
        # Only test the length of the line that contains the time.
224
        args = "--comments --header"
225
        gcode = postprocessor.export(postables, "-", args)
226
        # print("--------\n" + gcode + "--------\n")
227
        self.assertEqual(gcode.splitlines()[0], "(Exported by FreeCAD)")
228
        self.assertEqual(
229
            gcode.splitlines()[1],
230
            "(Post Processor: Path.Post.scripts.refactored_test_post)",
231
        )
232
        self.assertEqual(gcode.splitlines()[2], "(Cam File: )")
233
        self.assertIn("(Output Time: ", gcode.splitlines()[3])
234
        self.assertTrue(len(gcode.splitlines()[3]) == 41)
235
        self.assertEqual(gcode.splitlines()[4], "(Begin preamble)")
236
        self.assertEqual(gcode.splitlines()[5], "G90")
237
        self.assertEqual(gcode.splitlines()[6], "G21")
238
        self.assertEqual(gcode.splitlines()[7], "(Begin operation)")
239
        self.assertEqual(gcode.splitlines()[8], "(Finish operation: testpath)")
240
        self.assertEqual(gcode.splitlines()[9], "(Begin postamble)")
241

242
        # Test with comments without header.
243
        expected = """(Begin preamble)
244
G90
245
G21
246
(Begin operation)
247
(Finish operation: testpath)
248
(Begin postamble)
249
"""
250
        args = "--comments --no-header"
251
        gcode = postprocessor.export(postables, "-", args)
252
        # print("--------\n" + gcode + "--------\n")
253
        self.assertEqual(gcode, expected)
254

255
        # Test without comments with header.
256
        args = "--no-comments --header"
257
        gcode = postprocessor.export(postables, "-", args)
258
        # print("--------\n" + gcode + "--------\n")
259
        self.assertEqual(gcode.splitlines()[0], "(Exported by FreeCAD)")
260
        self.assertEqual(
261
            gcode.splitlines()[1],
262
            "(Post Processor: Path.Post.scripts.refactored_test_post)",
263
        )
264
        self.assertEqual(gcode.splitlines()[2], "(Cam File: )")
265
        self.assertIn("(Output Time: ", gcode.splitlines()[3])
266
        self.assertTrue(len(gcode.splitlines()[3]) == 41)
267
        self.assertEqual(gcode.splitlines()[4], "G90")
268
        self.assertEqual(gcode.splitlines()[5], "G21")
269

270
        # Test without comments or header.
271
        expected = """G90
272
G21
273
"""
274
        args = "--no-comments --no-header"
275
        gcode = postprocessor.export(postables, "-", args)
276
        # print("--------\n" + gcode + "--------\n")
277
        self.assertEqual(gcode, expected)
278

279
    #############################################################################
280

281
    def test00160(self):
282
        """Test Line Numbers."""
283
        self.compare_third_line(
284
            "G0 X10 Y20 Z30", "N120 G0 X10.000 Y20.000 Z30.000", "--line-numbers"
285
        )
286

287
    #############################################################################
288

289
    def test00170(self):
290
        """Test inches."""
291
        #
292
        c = Path.Command("G0 X10 Y20 Z30 A10 B20 C30 U10 V20 W30")
293

294
        self.docobj.Path = Path.Path([c])
295
        postables = [self.docobj]
296
        args = "--inches"
297
        gcode = postprocessor.export(postables, "-", args)
298
        # print("--------\n" + gcode + "--------\n")
299
        self.assertEqual(gcode.splitlines()[1], "G20")
300
        self.assertEqual(
301
            gcode.splitlines()[2],
302
            "G0 X0.3937 Y0.7874 Z1.1811 A0.3937 B0.7874 C1.1811 U0.3937 V0.7874 W1.1811",
303
        )
304

305
    #############################################################################
306

307
    def test00180(self):
308
        """Test modal.
309

310
        Suppress the command name if the same as previous
311
        """
312
        c = Path.Command("G0 X10 Y20 Z30")
313
        c1 = Path.Command("G0 X10 Y30 Z30")
314
        self.docobj.Path = Path.Path([c, c1])
315
        postables = [self.docobj]
316
        args = "--modal"
317
        gcode = postprocessor.export(postables, "-", args)
318
        # print("--------\n" + gcode + "--------\n")
319
        self.assertEqual(gcode.splitlines()[3], "X10.000 Y30.000 Z30.000")
320
        args = "--no-modal"
321
        gcode = postprocessor.export(postables, "-", args)
322
        # print("--------\n" + gcode + "--------\n")
323
        self.assertEqual(gcode.splitlines()[3], "G0 X10.000 Y30.000 Z30.000")
324

325
    #############################################################################
326

327
    def test00190(self):
328
        """Test Outputting all arguments.
329

330
        Empty path.  Outputs all arguments.
331
        """
332
        expected = """Arguments that are commonly used:
333
  --metric              Convert output for Metric mode (G21) (default)
334
  --inches              Convert output for US imperial mode (G20)
335
  --axis-modal          Don't output axis values if they are the same as the
336
                        previous line
337
  --no-axis-modal       Output axis values even if they are the same as the
338
                        previous line (default)
339
  --axis-precision AXIS_PRECISION
340
                        Number of digits of precision for axis moves, default
341
                        is 3
342
  --bcnc                Add Job operations as bCNC block headers. Consider
343
                        suppressing comments by adding --no-comments
344
  --no-bcnc             Suppress bCNC block header output (default)
345
  --comments            Output comments (default)
346
  --no-comments         Suppress comment output
347
  --feed-precision FEED_PRECISION
348
                        Number of digits of precision for feed rate, default
349
                        is 3
350
  --header              Output headers (default)
351
  --no-header           Suppress header output
352
  --line-numbers        Prefix with line numbers
353
  --no-line-numbers     Don't prefix with line numbers (default)
354
  --modal               Don't output the G-command name if it is the same as
355
                        the previous line
356
  --no-modal            Output the G-command name even if it is the same as
357
                        the previous line (default)
358
  --output_all_arguments
359
                        Output all of the available arguments
360
  --no-output_all_arguments
361
                        Don't output all of the available arguments (default)
362
  --output_visible_arguments
363
                        Output all of the visible arguments
364
  --no-output_visible_arguments
365
                        Don't output the visible arguments (default)
366
  --postamble POSTAMBLE
367
                        Set commands to be issued after the last command,
368
                        default is ""
369
  --preamble PREAMBLE   Set commands to be issued before the first command,
370
                        default is ""
371
  --precision PRECISION
372
                        Number of digits of precision for both feed rate and
373
                        axis moves, default is 3 for metric or 4 for inches
374
  --return-to RETURN_TO
375
                        Move to the specified x,y,z coordinates at the end,
376
                        e.g. --return-to=0,0,0 (default is do not move)
377
  --show-editor         Pop up editor before writing output (default)
378
  --no-show-editor      Don't pop up editor before writing output
379
  --tlo                 Output tool length offset (G43) following tool changes
380
                        (default)
381
  --no-tlo              Suppress tool length offset (G43) following tool
382
                        changes
383
  --tool_change         Insert M6 and any other tool change G-code for all
384
                        tool changes (default)
385
  --no-tool_change      Convert M6 to a comment for all tool changes
386
  --translate_drill     Translate drill cycles G73, G81, G82 & G83 into G0/G1
387
                        movements
388
  --no-translate_drill  Don't translate drill cycles G73, G81, G82 & G83 into
389
                        G0/G1 movements (default)
390
  --wait-for-spindle WAIT_FOR_SPINDLE
391
                        Time to wait (in seconds) after M3, M4 (default = 0.0)
392
"""
393
        self.docobj.Path = Path.Path([])
394
        postables = [self.docobj]
395
        gcode: str = postprocessor.export(postables, "-", "--output_all_arguments")
396
        # The argparse help routine turns out to be sensitive to the
397
        # number of columns in the terminal window that the tests
398
        # are run from.  This affects the indenting in the output.
399
        # The next couple of lines remove all of the white space.
400
        gcode = "".join(gcode.split())
401
        expected = "".join(expected.split())
402
        self.assertEqual(gcode, expected)
403

404
    #############################################################################
405

406
    def test00200(self):
407
        """Test Outputting visible arguments.
408

409
        Empty path.  Outputs visible arguments.
410
        """
411
        self.single_compare([], "", "--output_visible_arguments")
412

413
    #############################################################################
414

415
    def test00210(self):
416
        """Test Post-amble."""
417
        self.docobj.Path = Path.Path([])
418
        postables = [self.docobj]
419
        args = "--postamble='G0 Z50\nM2'"
420
        gcode = postprocessor.export(postables, "-", args)
421
        # print("--------\n" + gcode + "--------\n")
422
        self.assertEqual(gcode.splitlines()[-2], "G0 Z50")
423
        self.assertEqual(gcode.splitlines()[-1], "M2")
424

425
    #############################################################################
426

427
    def test00220(self):
428
        """Test Pre-amble."""
429
        self.docobj.Path = Path.Path([])
430
        postables = [self.docobj]
431
        args = "--preamble='G18 G55'"
432
        gcode = postprocessor.export(postables, "-", args)
433
        # print("--------\n" + gcode + "--------\n")
434
        self.assertEqual(gcode.splitlines()[0], "G18 G55")
435

436
    #############################################################################
437

438
    def test00230(self):
439
        """Test precision."""
440
        self.compare_third_line(
441
            "G1 X10 Y20 Z30 F100",
442
            "G1 X10.00 Y20.00 Z30.00 F6000.00",
443
            "--precision=2",
444
        )
445
        self.compare_third_line(
446
            "G1 X10 Y20 Z30 F100",
447
            "G1 X0.39 Y0.79 Z1.18 F236.22",
448
            "--inches --precision=2",
449
        )
450

451
    #############################################################################
452

453
    def test00240(self):
454
        """Test return-to."""
455
        self.compare_third_line("", "G0 X12 Y34 Z56", "--return-to='12,34,56'")
456

457
    #############################################################################
458

459
    def test00250(self):
460
        """Test tlo."""
461
        c = Path.Command("M6 T2")
462
        c2 = Path.Command("M3 S3000")
463
        self.docobj.Path = Path.Path([c, c2])
464
        postables = [self.docobj]
465
        args = "--tlo"
466
        gcode = postprocessor.export(postables, "-", args)
467
        # print("--------\n" + gcode + "--------\n")
468
        self.assertEqual(gcode.splitlines()[2], "M6 T2")
469
        self.assertEqual(gcode.splitlines()[3], "G43 H2")
470
        self.assertEqual(gcode.splitlines()[4], "M3 S3000")
471
        # suppress TLO
472
        args = "--no-tlo"
473
        gcode = postprocessor.export(postables, "-", args)
474
        # print("--------\n" + gcode + "--------\n")
475
        self.assertEqual(gcode.splitlines()[2], "M6 T2")
476
        self.assertEqual(gcode.splitlines()[3], "M3 S3000")
477

478
    #############################################################################
479

480
    def test00260(self):
481
        """Test tool_change."""
482
        c = Path.Command("M6 T2")
483
        c2 = Path.Command("M3 S3000")
484
        self.docobj.Path = Path.Path([c, c2])
485
        postables = [self.docobj]
486
        args = "--tool_change"
487
        gcode = postprocessor.export(postables, "-", args)
488
        # print("--------\n" + gcode + "--------\n")
489
        self.assertEqual(gcode.splitlines()[2], "M6 T2")
490
        self.assertEqual(gcode.splitlines()[3], "M3 S3000")
491
        args = "--comments --no-tool_change"
492
        gcode = postprocessor.export(postables, "-", args)
493
        # print("--------\n" + gcode + "--------\n")
494
        self.assertEqual(gcode.splitlines()[5], "( M6 T2 )")
495
        self.assertEqual(gcode.splitlines()[6], "M3 S3000")
496

497
    #############################################################################
498

499
    def test00270(self):
500
        """Test wait-for-spindle."""
501
        c = Path.Command("M3 S3000")
502
        self.docobj.Path = Path.Path([c])
503
        postables = [self.docobj]
504
        args = ""
505
        gcode = postprocessor.export(postables, "-", args)
506
        # print("--------\n" + gcode + "--------\n")
507
        self.assertEqual(gcode.splitlines()[2], "M3 S3000")
508
        args = "--wait-for-spindle=1.23456"
509
        gcode = postprocessor.export(postables, "-", args)
510
        # print("--------\n" + gcode + "--------\n")
511
        self.assertEqual(gcode.splitlines()[2], "M3 S3000")
512
        self.assertEqual(gcode.splitlines()[3], "G4 P1.23456")
513
        c = Path.Command("M4 S3000")
514
        self.docobj.Path = Path.Path([c])
515
        postables = [self.docobj]
516
        # This also tests that the default for --wait-for-spindle
517
        # goes back to 0.0 (no wait)
518
        args = ""
519
        gcode = postprocessor.export(postables, "-", args)
520
        # print("--------\n" + gcode + "--------\n")
521
        self.assertEqual(gcode.splitlines()[2], "M4 S3000")
522
        args = "--wait-for-spindle=1.23456"
523
        gcode = postprocessor.export(postables, "-", args)
524
        # print("--------\n" + gcode + "--------\n")
525
        self.assertEqual(gcode.splitlines()[2], "M4 S3000")
526
        self.assertEqual(gcode.splitlines()[3], "G4 P1.23456")
527

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.