gerber 0 → 1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ require 'minitest/autorun'
2
+ require 'gerber/layer'
3
+
4
+ describe Gerber::Layer do
5
+ let(:layer) { Gerber::Layer.new }
6
+ end
@@ -0,0 +1,481 @@
1
+ require 'minitest/autorun'
2
+ require 'gerber/layer/parser'
3
+
4
+ class Gerber
5
+ class Layer
6
+ class Parser
7
+ def geometry
8
+ self.layer.geometry
9
+ end
10
+
11
+ def dcode
12
+ @dcode
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ describe Gerber::Layer::Parser do
19
+ Arc = Gerber::Arc
20
+ Line = Gerber::Line
21
+ Point = Gerber::Point
22
+
23
+ let(:parser) { Gerber::Layer::Parser.new }
24
+
25
+ it "must default to absolute mode" do
26
+ parser.coordinate_mode.must_equal :absolute
27
+ end
28
+
29
+ it "must default to single quadrant mode" do
30
+ parser.quadrant_mode.must_equal :single
31
+ end
32
+
33
+ describe "when validating Geometry" do
34
+ it "must accept Arcs" do
35
+ parser.is_valid_geometry(Arc.new(nil, nil, nil, nil)).must_equal true
36
+ end
37
+
38
+ it "must accept Lines" do
39
+ parser.is_valid_geometry(Line.new).must_equal true
40
+ end
41
+
42
+ it "must accept Points" do
43
+ parser.is_valid_geometry(Point[0,0]).must_equal true
44
+ end
45
+ end
46
+
47
+ describe "when parsing a D code" do
48
+ it "must start drawing for D01" do
49
+ parser.parse_dcode('D01')
50
+ parser.dcode.must_equal 1
51
+ end
52
+
53
+ it "must stop drawing for D02" do
54
+ parser.parse_dcode('D02')
55
+ parser.dcode.must_equal 2
56
+ end
57
+
58
+ it "must flash for D03" do
59
+ parser.parse_dcode('D03')
60
+ parser.dcode.must_equal 3
61
+ end
62
+
63
+ it "must set the current aperture number" do
64
+ original_state = parser.dcode
65
+ parser.parse_dcode('D11')
66
+ parser.dcode.must_equal original_state
67
+ parser.current_aperture.must_equal 11
68
+ parser.geometry[11].must_be_instance_of(Array)
69
+ end
70
+ end
71
+
72
+ describe "when parsing a G code" do
73
+ it "must raise an exception if the units have not been set" do
74
+ lambda { parser.parse_gcode(1, 2, 3, 4, 5, 1) }.must_raise Gerber::ParseError
75
+ end
76
+
77
+ describe "when a G74 is parsed" do
78
+ before do
79
+ parser.parse_gcode(74)
80
+ end
81
+
82
+ it "must stay in single quadrant mode" do
83
+ parser.quadrant_mode.must_equal :single
84
+ end
85
+ end
86
+
87
+ describe "when a G75 is parsed" do
88
+ before do
89
+ parser.parse_gcode(75)
90
+ end
91
+
92
+ it "must set multi quadrant mode" do
93
+ parser.quadrant_mode.must_equal :multi
94
+ end
95
+
96
+ describe "when a G74 is parsed" do
97
+ before do
98
+ parser.parse_gcode(74)
99
+ end
100
+
101
+ it "must return to single quadrant mode" do
102
+ parser.quadrant_mode.must_equal :single
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "when G90 is parsed" do
108
+ before do
109
+ parser.parse_gcode(90)
110
+ end
111
+
112
+ it "must stay in absolute mode" do
113
+ parser.coordinate_mode.must_equal :absolute
114
+ end
115
+ end
116
+
117
+ describe "when G91 is parsed" do
118
+ before do
119
+ parser.parse_gcode(91)
120
+ end
121
+
122
+ it "must set incremental mode" do
123
+ parser.coordinate_mode.must_equal :incremental
124
+ end
125
+
126
+ describe "when a G90 is parsed" do
127
+ before do
128
+ parser.parse_gcode(90)
129
+ end
130
+
131
+ it "must return to absolute mode" do
132
+ parser.coordinate_mode.must_equal :absolute
133
+ end
134
+ end
135
+ end
136
+
137
+ describe "when units have been set" do
138
+ before do
139
+ parser.parse_gcode(71, nil, nil, nil, nil, nil)
140
+ end
141
+
142
+ it "must raise an exception if an aperture has not been set" do
143
+ lambda { parser.parse_gcode(1, 2, 3, 4, 5, 1) }.must_raise Gerber::ParseError
144
+ end
145
+
146
+ it "must parse the deprecated G54 and set the current aperture" do
147
+ parser.parse_gcode(54, nil, nil, nil, nil, 10)
148
+ parser.current_aperture.must_equal 10
149
+ parser.geometry[10].must_be_instance_of(Array)
150
+ end
151
+
152
+ it "must reject a G54 without a D code" do
153
+ skip "Not relevant in the latest version of the file format"
154
+ lambda { parser.parse_gcode(54, nil, nil, nil, nil, nil) }.must_raise Gerber::ParseError
155
+ end
156
+
157
+ describe "when an aperture has been set" do
158
+ before do
159
+ parser.current_aperture = 10
160
+ end
161
+
162
+ it "G1D1 must generate a Line" do
163
+ parser.parse_gcode(1, 2, 3, 4, 5, 1)
164
+ parser.geometry.last.last.must_be_kind_of(Geometry::Line)
165
+ end
166
+
167
+ it "G1D2 must move the current position but not generate geometry" do
168
+ parser.parse_gcode(1, 2, 3, 4, 5, 2)
169
+ parser.geometry.last.length.must_equal 0
170
+ parser.instance_variable_get(:@position).must_equal Geometry::Point[2.mm,3.mm]
171
+ end
172
+
173
+ it "G1D3 must generate a Point" do
174
+ parser.parse_gcode(1, 2, 3, 4, 5, 3)
175
+ parser.geometry.last.last.must_be_kind_of(Geometry::Point)
176
+ end
177
+
178
+ describe "when circular interpolation" do
179
+ it "must reject a dcode other than 1 or 2" do
180
+ skip
181
+ lambda { parser.parse_gcode(2, 1, 2, 3, 4, 5) }.must_raise Gerber::ParseError
182
+ lambda { parser.parse_gcode(3, 1, 2, 3, 4, 5) }.must_raise Gerber::ParseError
183
+ end
184
+
185
+ describe "when in absolute mode" do
186
+ describe "when in single quadrant mode" do
187
+ before do
188
+ parser.parse_gcode(74)
189
+ parser.parse_gcode(1, 11, 6, nil, nil, 2) # Set the current position
190
+ end
191
+
192
+ describe "when parsing four clockwise arcs" do
193
+ before do
194
+ parser.parse_gcode(2, 7, 2, 4, 0, 1)
195
+ parser.parse_gcode(2, 3, 6, 0, 4, nil)
196
+ parser.parse_gcode(nil, 7, 10, 4, 0, nil)
197
+ parser.parse_gcode(nil, 11, 6, 0, 4, nil)
198
+ end
199
+
200
+ it "must generate 4 Arcs" do
201
+ parser.geometry[10].length.must_equal 4
202
+ parser.geometry[10].all? {|a| a.kind_of?(Geometry::Arc)}.must_equal(true)
203
+ end
204
+
205
+ it "must generate a proper first Arc" do
206
+ arc = parser.geometry[10].first
207
+ arc.center.must_equal Point[7.mm, 6.mm]
208
+ arc.first.must_equal Point[7.mm, 2.mm]
209
+ arc.last.must_equal Point[11.mm, 6.mm]
210
+ end
211
+
212
+ it "must generate a proper second Arc" do
213
+ arc = parser.geometry[10][1]
214
+ arc.center.must_equal Point[7.mm, 6.mm]
215
+ arc.first.must_equal Point[3.mm, 6.mm]
216
+ arc.last.must_equal Point[7.mm, 2.mm]
217
+ end
218
+
219
+ it "must generate a proper third Arc" do
220
+ arc = parser.geometry[10][2]
221
+ arc.center.must_equal Point[7.mm, 6.mm]
222
+ arc.first.must_equal Point[7.mm, 10.mm]
223
+ arc.last.must_equal Point[3.mm, 6.mm]
224
+ end
225
+
226
+ it "must generate a proper fourth Arc" do
227
+ arc = parser.geometry[10].last
228
+ arc.center.must_equal Point[7.mm, 6.mm]
229
+ arc.first.must_equal Point[11.mm, 6.mm]
230
+ arc.last.must_equal Point[7.mm, 10.mm]
231
+ end
232
+ end
233
+
234
+ describe "when parsing a counterclockwise arc" do
235
+ before do
236
+ parser.parse_gcode(3, 7, 10, 4, 0, 1)
237
+ end
238
+
239
+ it "must generate an Arc" do
240
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
241
+ arc = parser.geometry[10].last
242
+ arc.center.must_equal Point[7.mm, 6.mm]
243
+ arc.first.must_equal Point[11.mm, 6.mm]
244
+ arc.last.must_equal Point[7.mm, 10.mm]
245
+ end
246
+
247
+ it "must set the current position to the Arc's end point" do
248
+ parser.position.must_equal Point[7.mm, 10.mm]
249
+ end
250
+
251
+ describe "when parsing another arc with a modal function number" do
252
+ before do
253
+ parser.parse_gcode(nil, 3, 6, 0, 4, nil)
254
+ end
255
+
256
+ it "must generate an Arc" do
257
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
258
+ arc = parser.geometry[10].last
259
+ arc.center.must_equal Point[7.mm, 6.mm]
260
+ arc.first.must_equal Point[7.mm, 10.mm]
261
+ arc.last.must_equal Point[3.mm, 6.mm]
262
+ end
263
+
264
+ it "must set the current position to the Arc's end point" do
265
+ parser.position.must_equal Point[3.mm, 6.mm]
266
+ end
267
+
268
+ describe "when parsing a third arc" do
269
+ before do
270
+ parser.parse_gcode(nil, 7, 2, 4, 0, nil)
271
+ end
272
+
273
+ it "must generate an Arc" do
274
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
275
+ arc = parser.geometry[10].last
276
+ arc.center.must_equal Point[7.mm, 6.mm]
277
+ arc.first.must_equal Point[3.mm, 6.mm]
278
+ arc.last.must_equal Point[7.mm, 2.mm]
279
+ end
280
+
281
+ it "must set the current position to the Arc's end point" do
282
+ parser.position.must_equal Point[7.mm, 2.mm]
283
+ end
284
+
285
+ describe "when parsing the final arc in the circle" do
286
+ before do
287
+ parser.parse_gcode(nil, 11, 6, 0, 4, nil)
288
+ end
289
+
290
+ it "must generate an Arc" do
291
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
292
+ arc = parser.geometry[10].last
293
+ arc.center.must_equal Point[7.mm, 6.mm]
294
+ arc.first.must_equal Point[7.mm, 2.mm]
295
+ arc.last.must_equal Point[11.mm, 6.mm]
296
+ end
297
+
298
+ it "must set the current position to the Arc's end point" do
299
+ parser.position.must_equal Point[11.mm, 6.mm]
300
+ end
301
+ end
302
+ end
303
+ end
304
+ end
305
+ end
306
+
307
+ describe "when in multi quadrant mode" do
308
+ before do
309
+ parser.parse_gcode(75)
310
+ parser.parse_gcode(1, 3, -2, nil, nil, 2) # Set the current position
311
+ end
312
+
313
+ describe "when parsing a clockwise arc" do
314
+ before do
315
+ parser.parse_gcode(2, -3, -2, -3, 4, 1)
316
+ end
317
+
318
+ it "must generate an Arc" do
319
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
320
+ arc = parser.geometry[10].last
321
+ arc.center.must_equal Point[0.mm, 2.mm]
322
+ arc.first.must_equal Point[-3.mm, -2.mm]
323
+ arc.last.must_equal Point[3.mm, -2.mm]
324
+ end
325
+
326
+ it "must set the current position to the endpoint of the Arc" do
327
+ parser.position.must_equal Point[-3.mm, -2.mm]
328
+ end
329
+ end
330
+
331
+ describe "when parsing a counterclockwise arc" do
332
+ before do
333
+ parser.parse_gcode(3, -3, -2, -3, 4, 1)
334
+ end
335
+
336
+ it "must generate an Arc" do
337
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
338
+ arc = parser.geometry[10].last
339
+ arc.center.must_equal Point[0.mm, 2.mm]
340
+ arc.first.must_equal Point[3.mm, -2.mm]
341
+ arc.last.must_equal Point[-3.mm, -2.mm]
342
+ end
343
+
344
+ it "must set the current position to the endpoint of the Arc" do
345
+ parser.position.must_equal Point[-3.mm, -2.mm]
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ describe "when in incremental mode" do
352
+ before do
353
+ parser.parse_gcode(91)
354
+ end
355
+
356
+ describe "when in single quadrant mode" do
357
+ before do
358
+ parser.parse_gcode(74)
359
+ parser.parse_gcode(1, 11, 6, nil, nil, 2) # Set the current position
360
+ end
361
+
362
+ describe "when parsing four clockwise arcs" do
363
+ before do
364
+ parser.parse_gcode(2, -4, -4, 4, 0, 1)
365
+ parser.parse_gcode(2, -4, 4, 0, 4, nil)
366
+ parser.parse_gcode(nil, 4, 4, 4, 0, nil)
367
+ parser.parse_gcode(nil, 4, -4, 0, 4, nil)
368
+ end
369
+
370
+ it "must generate 4 Arcs" do
371
+ parser.geometry[10].length.must_equal 4
372
+ parser.geometry[10].all? {|a| a.kind_of?(Geometry::Arc)}.must_equal(true)
373
+ end
374
+
375
+ it "must generate a proper first Arc" do
376
+ arc = parser.geometry[10].first
377
+ arc.center.must_equal Point[7.mm, 6.mm]
378
+ arc.first.must_equal Point[7.mm, 2.mm]
379
+ arc.last.must_equal Point[11.mm, 6.mm]
380
+ end
381
+
382
+ it "must generate a proper second Arc" do
383
+ arc = parser.geometry[10][1]
384
+ arc.center.must_equal Point[7.mm, 6.mm]
385
+ arc.first.must_equal Point[3.mm, 6.mm]
386
+ arc.last.must_equal Point[7.mm, 2.mm]
387
+ end
388
+
389
+ it "must generate a proper third Arc" do
390
+ arc = parser.geometry[10][2]
391
+ arc.center.must_equal Point[7.mm, 6.mm]
392
+ arc.first.must_equal Point[7.mm, 10.mm]
393
+ arc.last.must_equal Point[3.mm, 6.mm]
394
+ end
395
+
396
+ it "must generate a proper fourth Arc" do
397
+ arc = parser.geometry[10].last
398
+ arc.center.must_equal Point[7.mm, 6.mm]
399
+ arc.first.must_equal Point[11.mm, 6.mm]
400
+ arc.last.must_equal Point[7.mm, 10.mm]
401
+ end
402
+ end
403
+
404
+ describe "when parsing a counterclockwise arc" do
405
+ before do
406
+ parser.parse_gcode(3, -4, 4, 4, 0, 1)
407
+ end
408
+
409
+ it "must generate an Arc" do
410
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
411
+ arc = parser.geometry[10].last
412
+ arc.center.must_equal Point[7.mm, 6.mm]
413
+ arc.first.must_equal Point[11.mm, 6.mm]
414
+ arc.last.must_equal Point[7.mm, 10.mm]
415
+ end
416
+
417
+ it "must set the current position to the Arc's end point" do
418
+ parser.position.must_equal Point[7.mm, 10.mm]
419
+ end
420
+
421
+ describe "when parsing another arc with a modal function number" do
422
+ before do
423
+ parser.parse_gcode(nil, -4, -4, 0, 4, nil)
424
+ end
425
+
426
+ it "must generate an Arc" do
427
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
428
+ arc = parser.geometry[10].last
429
+ arc.center.must_equal Point[7.mm, 6.mm]
430
+ arc.first.must_equal Point[7.mm, 10.mm]
431
+ arc.last.must_equal Point[3.mm, 6.mm]
432
+ end
433
+
434
+ it "must set the current position to the Arc's end point" do
435
+ parser.position.must_equal Point[3.mm, 6.mm]
436
+ end
437
+
438
+ describe "when parsing a third arc" do
439
+ before do
440
+ parser.parse_gcode(nil, 4, -4, 4, 0, nil)
441
+ end
442
+
443
+ it "must generate an Arc" do
444
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
445
+ arc = parser.geometry[10].last
446
+ arc.center.must_equal Point[7.mm, 6.mm]
447
+ arc.first.must_equal Point[3.mm, 6.mm]
448
+ arc.last.must_equal Point[7.mm, 2.mm]
449
+ end
450
+
451
+ it "must set the current position to the Arc's end point" do
452
+ parser.position.must_equal Point[7.mm, 2.mm]
453
+ end
454
+
455
+ describe "when parsing the final arc in the circle" do
456
+ before do
457
+ parser.parse_gcode(nil, 4, 4, 0, 4, nil)
458
+ end
459
+
460
+ it "must generate an Arc" do
461
+ parser.geometry[10].last.must_be_kind_of(Geometry::Arc)
462
+ arc = parser.geometry[10].last
463
+ arc.center.must_equal Point[7.mm, 6.mm]
464
+ arc.first.must_equal Point[7.mm, 2.mm]
465
+ arc.last.must_equal Point[11.mm, 6.mm]
466
+ end
467
+
468
+ it "must set the current position to the Arc's end point" do
469
+ parser.position.must_equal Point[11.mm, 6.mm]
470
+ end
471
+ end
472
+ end
473
+ end
474
+ end
475
+ end
476
+ end
477
+ end
478
+ end
479
+ end
480
+ end
481
+ end