UNPKG

@tracespace/parser

Version:
417 lines (410 loc) 11.1 kB
// gerber grammar tests import {expect} from 'chai' import {toArray} from 'lodash' import * as Lexer from '../../lexer' import * as Tree from '../../tree' import { token as t, position as pos, simplifyToken, } from '../../__tests__/helpers' import {matchSyntax, MatchState} from '..' import { GERBER, CIRCLE, RECTANGLE, OBROUND, POLYGON, MACRO_SHAPE, } from '../../constants' const SPECS: Array<{ source: string expectedTokens: Lexer.Token[] expectedNodes: Tree.ChildNode[] }> = [ { // simple circle tool source: '%ADD10C,.025*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '10C'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '.025'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 13, 12]), code: '10', shape: {type: CIRCLE, diameter: 0.025}, hole: null, }, ], }, { // circle tool with circular hole source: '%ADD11C,0.5X0.25*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '11C'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.25'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 17, 16]), code: '11', shape: {type: CIRCLE, diameter: 0.5}, hole: {type: CIRCLE, diameter: 0.25}, }, ], }, { // circle tool with rectangular hole source: '%ADD12C,10X5X5*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '12C'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '10'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '5'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 15, 14]), code: '12', shape: {type: CIRCLE, diameter: 10}, hole: {type: RECTANGLE, xSize: 5, ySize: 5}, }, ], }, { // rectangle tool definition with no hole source: '%ADD13R,0.5X0.6*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '13R'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 16, 15]), code: '13', shape: {type: RECTANGLE, xSize: 0.5, ySize: 0.6}, hole: null, }, ], }, { // rectangle tool definition with circle hole source: '%ADD14R,0.5X0.6X0.2*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '14R'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.2'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 20, 19]), code: '14', shape: {type: RECTANGLE, xSize: 0.5, ySize: 0.6}, hole: {type: CIRCLE, diameter: 0.2}, }, ], }, { // rectangle tool definition with rectangle hole source: '%ADD15R,0.5X0.6X0.2X0.1*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '15R'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.2'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.1'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 24, 23]), code: '15', shape: {type: RECTANGLE, xSize: 0.5, ySize: 0.6}, hole: {type: RECTANGLE, xSize: 0.2, ySize: 0.1}, }, ], }, { // obround tool definition with no hole source: '%ADD16O,0.5X0.6*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '16O'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 16, 15]), code: '16', shape: {type: OBROUND, xSize: 0.5, ySize: 0.6}, hole: null, }, ], }, { // obround tool definition with circle hole source: '%ADD17O,0.5X0.6X0.2*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '17O'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.2'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 20, 19]), code: '17', shape: {type: OBROUND, xSize: 0.5, ySize: 0.6}, hole: {type: CIRCLE, diameter: 0.2}, }, ], }, { // obround tool definition with rectangle hole source: '%ADD18O,0.5X0.6X0.2X0.1*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '18O'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.6'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.2'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.1'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 24, 23]), code: '18', shape: {type: OBROUND, xSize: 0.5, ySize: 0.6}, hole: {type: RECTANGLE, xSize: 0.2, ySize: 0.1}, }, ], }, { // polygon tool definition with no rotation and no hole source: '%ADD19P,1.5X3*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '19P'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '1.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '3'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 14, 13]), code: '19', shape: {type: POLYGON, diameter: 1.5, vertices: 3, rotation: null}, hole: null, }, ], }, { // polygon tool defintion with rotation and no hole source: '%ADD20P,2.5X4X12.5*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '20P'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '2.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '4'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '12.5'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 19, 18]), code: '20', shape: {type: POLYGON, diameter: 2.5, vertices: 4, rotation: 12.5}, hole: null, }, ], }, { // polygon tool definition with rotation and circle hole source: '%ADD21P,2.5X4X12.5X1*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '21P'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '2.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '4'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '12.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '1'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 21, 20]), code: '21', shape: {type: POLYGON, diameter: 2.5, vertices: 4, rotation: 12.5}, hole: {type: CIRCLE, diameter: 1}, }, ], }, { // polygon tool definition with rotation and circle hole source: '%ADD22P,2.5X4X12.5X1X1.5*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '22P'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '2.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '4'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '12.5'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '1'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '1.5'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 25, 24]), code: '22', shape: {type: POLYGON, diameter: 2.5, vertices: 4, rotation: 12.5}, hole: {type: RECTANGLE, xSize: 1, ySize: 1.5}, }, ], }, { // macro tool definition with no parameters source: '%ADD23MyMacro*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '23MyMacro'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 14, 13]), code: '23', shape: {type: MACRO_SHAPE, name: 'MyMacro', params: []}, hole: null, }, ], }, { // macro tool definition with parameters source: '%ADD24MyMacro,0.1X0.2X0.3*%', expectedTokens: [ t(Lexer.PERCENT, '%'), t(Lexer.GERBER_TOOL_DEF, '24MyMacro'), t(Lexer.COMMA, ','), t(Lexer.NUMBER, '0.1'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.2'), t(Lexer.COORD_CHAR, 'X'), t(Lexer.NUMBER, '0.3'), t(Lexer.ASTERISK, '*'), t(Lexer.PERCENT, '%'), ], expectedNodes: [ { type: Tree.TOOL_DEFINITION, position: pos([1, 2, 1], [1, 26, 25]), code: '24', shape: {type: MACRO_SHAPE, name: 'MyMacro', params: [0.1, 0.2, 0.3]}, hole: null, }, ], }, ] describe('gerber tool syntax matches', () => { SPECS.forEach(({source, expectedTokens, expectedNodes}) => { it(`should match on ${source.trim()}`, () => { const lexer = Lexer.createLexer() lexer.reset(source) const actualTokens = toArray((lexer as unknown) as Array<Lexer.Token>) const {tokens, nodes, filetype} = actualTokens.reduce<MatchState>( (state, token) => matchSyntax(state, token), null ) expect(filetype).to.equal(GERBER) expect(nodes).to.eql(expectedNodes) expect(tokens.map(simplifyToken)).to.eql( expectedTokens.map(simplifyToken) ) }) }) })