UNPKG

swift-pattern-compiler

Version:

A compiler which transforms SWIFT patterns to an object representation with additional information's.

756 lines (748 loc) 25.8 kB
import * as test from "tape"; import { generator, getCharClass, getQuantifier } from "../src/generator"; import { ENodeType } from "../src/interfaces"; import { ITest } from "./testInterfaces"; test("objectGenerator module", t => { t.plan(1); t.ok( typeof generator === "function", "expect swiftObjectGenerator to be a function", ); }); test("objectGenerator call", t => { const tests: ITest[] = [ { msg: "should parse 35a AST", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 35 }, char: "a", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 35, regExp: "[A-Z]{0,35}", allowedCharsClass: "[A-Z]", }, ], minChars: 0, maxChars: 35, regExp: "[A-Z]{0,35}", allowedCharsClass: "[A-Z]", }, }, { msg: "should parse 4a AST", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 4 }, char: "a", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 4, regExp: "[A-Z]{0,4}", allowedCharsClass: "[A-Z]", }, ], minChars: 0, maxChars: 4, regExp: "[A-Z]{0,4}", allowedCharsClass: "[A-Z]", }, }, { msg: "should parse 4a3c AST", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 4 }, char: "a", }, { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 7, regExp: "[A-Z]{0,4}[A-Z0-9]{0,3}", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 7, regExp: "[A-Z]{0,4}[A-Z0-9]{0,3}", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate :4!c object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.sign, char: ":", }, { type: ENodeType.field, length: { min: 4, max: 4 }, char: "c", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 5, maxChars: 5, regExp: ":[A-Z0-9]{4,4}", allowedCharsClass: "[:A-Z0-9]", }, ], minChars: 5, maxChars: 5, regExp: ":[A-Z0-9]{4,4}", allowedCharsClass: "[:A-Z0-9]", }, }, { // tslint:disable-next-line:max-line-length msg: "generate :: object, filter out duplicates in allowedCharsClass", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.sign, char: ":", }, { type: ENodeType.sign, char: ":", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 2, maxChars: 2, regExp: "::", allowedCharsClass: "[:]", }, ], minChars: 2, maxChars: 2, regExp: "::", allowedCharsClass: "[:]", }, }, { msg: "generate multiline 3a\\n4c\\n4c object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 30 }, char: "a", }, ], }, { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 4 }, char: "c", }, ], }, { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 4 }, char: "c", }, ], }, ], }), expected: { linesCount: 3, lines: [ { minChars: 0, maxChars: 30, regExp: "[A-Z]{0,30}", allowedCharsClass: "[A-Z]", }, { minChars: 0, maxChars: 4, regExp: "[A-Z0-9]{0,4}", allowedCharsClass: "[A-Z0-9]", }, { minChars: 0, maxChars: 4, regExp: "[A-Z0-9]{0,4}", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 38, regExp: "[A-Z]{0,30}\n[A-Z0-9]{0,4}\n[A-Z0-9]{0,4}", allowedCharsClass: "[A-Z\nA-Z0-9]", }, }, { msg: "generate multiline 30a\\n4c object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 30 }, char: "a", }, ], }, { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 4 }, char: "c", }, ], }, ], }), expected: { linesCount: 2, lines: [ { minChars: 0, maxChars: 30, regExp: "[A-Z]{0,30}", allowedCharsClass: "[A-Z]", }, { minChars: 0, maxChars: 4, regExp: "[A-Z0-9]{0,4}", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 34, regExp: "[A-Z]{0,30}\n[A-Z0-9]{0,4}", allowedCharsClass: "[A-Z\nA-Z0-9]", }, }, { msg: "generate multiline 2*35a object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, optional: true, nodes: [ { type: ENodeType.field, length: { min: 0, max: 35 }, char: "a", }, ], }, { type: ENodeType.line, optional: true, nodes: [ { type: ENodeType.field, length: { min: 0, max: 35 }, char: "a", }, ], }, ], }), expected: { linesCount: 2, lines: [ { minChars: 0, maxChars: 35, regExp: "[A-Z]{0,35}", allowedCharsClass: "[A-Z]", }, { minChars: 0, maxChars: 35, regExp: "[A-Z]{0,35}", allowedCharsClass: "[A-Z]", }, ], minChars: 0, maxChars: 70, regExp: "([A-Z]{0,35})?\n?([A-Z]{0,35})?", allowedCharsClass: "[A-Z\n]", }, }, { msg: "generate [3c] object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, ], }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 3, regExp: "([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 3, regExp: "([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate [3c] object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, ], }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 3, regExp: "([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 3, regExp: "([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate required with trailing optional 2!a[3c] object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 2, max: 2 }, char: "a", }, { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, ], }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 2, maxChars: 5, regExp: "[A-Z]{2,2}([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 2, maxChars: 5, regExp: "[A-Z]{2,2}([A-Z0-9]{0,3})?", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate optional with trailing required [3c]2!a object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, ], }, { type: ENodeType.field, length: { min: 2, max: 2 }, char: "a", }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 2, maxChars: 5, regExp: "([A-Z0-9]{0,3})?[A-Z]{2,2}", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 2, maxChars: 5, regExp: "([A-Z0-9]{0,3})?[A-Z]{2,2}", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate nested optional [3c[3!c]] object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 0, max: 3 }, char: "c", }, { type: ENodeType.optional, nodes: [ { type: ENodeType.field, length: { min: 3, max: 3 }, char: "c", }, ], }, ], }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 6, regExp: "([A-Z0-9]{0,3}([A-Z0-9]{3,3})?)?", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 6, regExp: "([A-Z0-9]{0,3}([A-Z0-9]{3,3})?)?", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "generate block (1a1n) object", actual: generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.block, nodes: [ { type: ENodeType.field, length: { min: 0, max: 1 }, char: "a", }, { type: ENodeType.field, length: { min: 0, max: 1 }, char: "n", }, ], }, ], }, ], }), expected: { linesCount: 1, lines: [ { minChars: 0, maxChars: 2, regExp: "([A-Z]?[0-9]?)", allowedCharsClass: "[A-Z0-9]", }, ], minChars: 0, maxChars: 2, regExp: "([A-Z]?[0-9]?)", allowedCharsClass: "[A-Z0-9]", }, }, { msg: "throws when wrong AST type is supplied", method: "throws", actual: () => generator({ type: "Programm", body: [], }), expected: /Unsupported AST type "Programm"/, }, { msg: "throws when unsupported char is supplied", method: "throws", actual: () => generator({ type: "SwiftPattern", body: [ { type: ENodeType.line, nodes: [ { type: ENodeType.field, length: { min: 0, max: 35 }, char: "ö", }, ], }, ], }), expected: /Unsupported character "ö" in field/, }, ]; t.plan(tests.length); tests.forEach(({ actual, expected, msg = "", method = "deepEqual", }) => { t[method](actual, expected, msg); }); }); test("getCharClass call", t => { const tests: ITest[] = [ { msg: "returns the char class for a", actual: getCharClass("a"), expected: "[A-Z]", }, { msg: "returns the char class for n", actual: getCharClass("n"), expected: "[0-9]", }, { msg: "returns the char class for x", actual: getCharClass("x"), expected: "[A-Za-z0-9\\/\\-\\?\\:\\(\\)\\.\\,\\'\\+\n ]", }, { msg: "returns the char class for y", actual: getCharClass("y"), // tslint:disable-next-line:max-line-length expected: `[A-Z0-9\\.\\,\\-\\(\\)\\/\\=\\'\\+\\:\\?\\!\\"\\%\\&\\*\\<\\>\\; ]`, }, { msg: "returns the char class for z", actual: getCharClass("z"), // tslint:disable-next-line:max-line-length expected: `[A-Za-z0-9\\.\\,\\-\\(\\)\\/\\=\\'\\+\\:\\?\\!\\"\\%\\&\\*\\<\\>\\;\\{\\@\\#\\_\n ]`, }, { msg: "returns the char class for c", actual: getCharClass("c"), expected: `[A-Z0-9]`, }, { msg: "returns the char class for h", actual: getCharClass("h"), expected: `[A-F0-9]`, }, { msg: "returns the char class for e", actual: getCharClass("e"), expected: `[ ]`, }, { msg: "returns the char class for d", actual: getCharClass("d"), expected: `[0-9,]`, }, { msg: "returns empty string for undefined char class ö", actual: getCharClass("ö"), expected: "", }, ]; t.plan(tests.length); tests.forEach(({ actual, expected, msg = "", method = "deepEqual", }) => { t[method](actual, expected, msg); }); }); test("getQuantifier call", t => { const tests: ITest[] = [ { msg: "returns the quantifier for 1,2", actual: getQuantifier(1, 2), expected: "{1,2}", }, { msg: "returns the quantifier for 1,1", actual: getQuantifier(1, 1), expected: "", }, { msg: "returns the quantifier for 0,1", actual: getQuantifier(0, 1), expected: "?", }, { msg: "throws when min > max", method: "throws", actual: () => getQuantifier(1, 0), expected: /Invalid quantifier, max "0" has to be equal or greater than min "1"/, }, ]; t.plan(tests.length); tests.forEach(({ actual, expected, msg = "", method = "deepEqual", }) => { t[method](actual, expected, msg); }); });