diff --git a/src/parse-dsl.ts b/src/parse-dsl.ts index 3ca88f5..fabcf64 100644 --- a/src/parse-dsl.ts +++ b/src/parse-dsl.ts @@ -44,10 +44,14 @@ export interface ParserResult { types: TypeDefParserResult[]; } -export const parseDSL = (code: string): ParserResult => { +export const innerParseDSL = (code: string): ParserResult[] => { const parser = new Parser(Grammar.fromCompiled(grammar)); parser.feed(code.trim() + "\n"); - return parser.results[0] || []; + return parser.results; +}; + +export const parseDSL = (code: string): ParserResult => { + return innerParseDSL(code)[0] || []; }; // The TransformedType allows us to quickly access the various relations unique by diff --git a/tests/dsl.test.ts b/tests/dsl.test.ts index 38fc877..5a8c74c 100644 --- a/tests/dsl.test.ts +++ b/tests/dsl.test.ts @@ -1,5 +1,5 @@ import { checkDSL } from "../src"; -import { parseDSL } from "../src/parse-dsl"; +import { innerParseDSL, parseDSL } from "../src/parse-dsl"; describe("DSL", () => { describe("parseDSL()", () => { @@ -49,6 +49,285 @@ type app }); }); + describe("innerParseDSL()", () => { + it("should only return single result for simple valid model", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with non direct result", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with non direct result and spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with intersection", () => { + const result = innerParseDSL(`type team + relations + define member as self + define myfriend as self + define other as self or member or myfriend +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with intersection and spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as self or member or myfriend +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with union", () => { + const result = innerParseDSL(`type team + relations + define member as self + define myfriend as self + define other as self and member and myfriend +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with union and spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define myfriend as self + define other as self and member and myfriend +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with but not", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as self but not member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with but not and spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define other as self but not member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with tuple to userset", () => { + const result = innerParseDSL(`type team + relations + define viewer as self + define parent as self + define can_view as viewer from parent +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with tuple to userset and spaces", () => { + const result = innerParseDSL(`type team + relations + define viewer as self + define parent as self + define can_view as viewer from parent +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with but not + tuple to userset", () => { + const result = innerParseDSL(`type team + relations + define member as self + define parent as self + define viewer as self + define other as viewer from parent but not member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with but not + tuple to userset and spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + define parent as self + define viewer as self + define other as viewer from parent but not member +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with multiple types", () => { + const result = innerParseDSL(`type team + relations + define viewer as self +type group + relations + define parent as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with multiple types and empty lines", () => { + const result = innerParseDSL(`type team + relations + define viewer as self + + +type group + relations + define parent as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple valid model with multiple types and empty lines + spaces", () => { + const result = innerParseDSL(`type team + relations + define viewer as self + + +type group + relations + define parent as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple 1.1 valid model", () => { + const result = innerParseDSL(`type user +type team + relations + define member: [user] as self + define other: [user] as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple 1.1 valid model with spaces", () => { + const result = innerParseDSL(`type user +type team + relations + define member: [user] as self + define other: [user] as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple 1.1 valid model with comment", () => { + const result = innerParseDSL(`type user +type team + relations + define member: [user] as self + # Comment for other + define other: [user] as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for simple 1.1 valid model with comment and spaces at the end", () => { + const result = innerParseDSL(`type user +type team + relations + define member: [user] as self + # Comment for other + define other: [user] as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for complex valid model", () => { + const result = innerParseDSL(`type team + relations + define member as self + +type repo + relations + define admin as self or repo_admin from owner + define maintainer as self or admin + define owner as self + define reader as self or triager or repo_reader from owner + define triager as self or writer + define writer as self or maintainer or repo_writer from owner + +type org + relations + define billing_manager as self or owner + define member as self or owner + define owner as self + define repo_admin as self + define repo_reader as self + define repo_writer as self + +type app + relations + define app_manager as self or owner from owner + define owner as self +`); + expect(result.length).toEqual(1); + }); + + it("should only return single result for complex model with spaces", () => { + const result = innerParseDSL(`type team + relations + define member as self + +type repo + relations + + define admin as self or repo_admin from owner + define maintainer as self or admin + define owner as self + define reader as self or triager or repo_reader from owner + define triager as self or writer + define writer as self or maintainer or repo_writer from owner + +type org + relations + define billing_manager as self or owner + define member as self or owner + define owner as self + define repo_admin as self + define repo_reader as self + define repo_writer as self + +type app + relations + define app_manager as self or owner from owner + define owner as self +`); + expect(result.length).toEqual(1); + }); + }); + describe("checkDSL()", () => { it("should correctly parse a simple sample", () => { const markers = checkDSL(`type group