Skip to content

Commit

Permalink
Report an error on invalid line assertions. Add support for split ^
Browse files Browse the repository at this point in the history
  • Loading branch information
PanAeon committed Apr 23, 2020
1 parent a563868 commit f6090e7
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 501 deletions.
682 changes: 251 additions & 431 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@
"author": "vitalii voloshyn",
"license": "MIT",
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/glob": "^7.1.1",
"@types/mocha": "^5.2.6",
"@types/node": "^12.0.0",
"@types/chai": "^4.2.11",
"@types/diff": "^4.0.2",
"@types/glob": "^7.1.1",
"@types/mocha": "^5.2.7",
"@types/node": "^12.12.37",
"chai": "^4.2.0",
"tslint": "^5.16.0",
"typescript": "^3.4.5",
"ts-node": "^8.1.0",
"mocha": "^6.2.0"
"mocha": "^6.2.3",
"ts-node": "^8.9.0",
"tslint": "^5.20.1",
"typescript": "^3.8.3"
},
"dependencies": {
"chalk": "^2.4.2",
"commander": "^2.20.0",
"diff": "^4.0.1",
"glob": "^7.1.4",
"commander": "^2.20.3",
"diff": "^4.0.2",
"glob": "^7.1.6",
"vscode-textmate": "^4.1.1"
}
}
10 changes: 9 additions & 1 deletion shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ stdenv.mkDerivation {
# The packages in the `buildInputs` list will be added to the PATH in our shell
buildInputs = [
# see https://nixos.org/nixos/packages.html to search for more
pkgs.nodejs-10_x coreutils nodePackages_10_x.node-gyp nodePackages_10_x.node-gyp-build nodePackages_10_x.node-pre-gyp nodePackages_10_x.typescript pkgs.python
pkgs.nodejs-12_x
coreutils
pkgs.python
# pkgs.nodejs-12_x coreutils
# nodePackages_12_x.node-gyp
# nodePackages_12_x.node-gyp-build
# nodePackages_12_x.node-pre-gyp
# nodePackages_12_x.typescript
# pkgs.python
];
}
56 changes: 34 additions & 22 deletions src/unit/parsing.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,40 @@

import { ScopeAssertion, TestCaseMetadata, LineAssertion, GrammarTestCase } from './model';
// import { start } from 'repl';

const leftArrowAssertRegex = /^\s*<([~]*)([-]+)((?:\s*\w[-\w.]*)*)(?:\s*-)?((?:\s*\w[-\w.]*)*)\s*$/
const upArrowAssertRegex = /^\s*(\^+)((?:\s*\w[-\w.]*)*)(?:\s*-)?((?:\s*\w[-\w.]*)*)\s*$/
const upArrowAssertRegex = /^\s*((?:(?:\^+)\s*)+)((?:\s*\w[-\w.]*)*)(?:\s*-)?((?:\s*\w[-\w.]*)*)\s*$/


export function parseScopeAssertion(testCaseLineNumber: number, commentLength: number, as: String): ScopeAssertion | void {
export function parseScopeAssertion(testCaseLineNumber: number, commentLength: number, as: String): ScopeAssertion[] {
let s = as.slice(commentLength)

let upArrowMatch = upArrowAssertRegex.exec(s)
if (s.trim().startsWith('^')) {
let upArrowMatch = upArrowAssertRegex.exec(s)
if (upArrowMatch !== null) {
let [,, scopes = "", exclusions = ""] = upArrowMatch

if (upArrowMatch !== null) {
let [_, arrows, scopes = "", exclusions = ""] = upArrowMatch
let startIdx = commentLength + s.indexOf("^")
if (scopes === "" && exclusions === "") {
return undefined;
} else {
return <ScopeAssertion>{
from: startIdx,
to: startIdx + arrows.length,
scopes: scopes.split(/\s+/).filter((x) => x),
exclude: exclusions.split(/\s+/).filter((x) => x)

if (scopes === "" && exclusions === "") {
throw new Error(`Inalid assertion at line ${testCaseLineNumber}:\n${as}\n Missing both required and prohibited scopes`)
} else {
const result = []
let startIdx = s.indexOf("^")
while(startIdx !== -1) {
let endIndx = startIdx
while(s[endIndx + 1] === '^') { endIndx++ }
result.push(<ScopeAssertion>{
from: commentLength + startIdx,
to: commentLength + endIndx + 1,
scopes: scopes.split(/\s+/).filter((x) => x),
exclude: exclusions.split(/\s+/).filter((x) => x)
})
startIdx = s.indexOf("^", endIndx+1)
}
return result;
}
} else {
throw new Error(`Inalid assertion at line ${testCaseLineNumber}:\n${as}\n`)
}
}

Expand All @@ -30,18 +43,18 @@ export function parseScopeAssertion(testCaseLineNumber: number, commentLength: n
if (leftArrowMatch !== null) {
let [_, tildas, dashes, scopes = "", exclusions = ""] = leftArrowMatch
if (scopes === "" && exclusions === "") {
return undefined;
throw new Error(`Inalid assertion at line ${testCaseLineNumber}:\n${as}\n Missing both required and prohibited scopes`)
} else {
return <ScopeAssertion>{
return [{
from: tildas.length,
to: tildas.length + dashes.length,
scopes: scopes.split(/\s+/).filter((x) => x),
exclude: exclusions.split(/\s+/).filter((x) => x)
}
}]
}
}

return undefined;
return [];

}

Expand Down Expand Up @@ -100,10 +113,9 @@ export function parseGrammarTestCase(str: string): GrammarTestCase {
let tcLineNumber = headerLength + i;

if (s.startsWith(commentToken)) {
let a = parseScopeAssertion(tcLineNumber, commentToken.length, s)
if (a !== undefined) {
currentLineAssertion.scopeAssertions.push(a);
}
let as = parseScopeAssertion(tcLineNumber, commentToken.length, s)
currentLineAssertion.scopeAssertions = [...currentLineAssertion.scopeAssertions, ...as]

// if (!skipComments) {
// source.push(s)
// sourceLineNumber++;
Expand Down
2 changes: 1 addition & 1 deletion test/resources/snaps/simple.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-}

-- comment
let user = "bill"
let user = "bill"
in { home = "/home/${user}"
, privateKey = "/home/${user}/id_ed25519"
, publicKey = "/home/${user}/id_ed25519.pub"
Expand Down
3 changes: 1 addition & 2 deletions test/resources/snaps/simple.dhall.snap
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
>-- comment
#^^ source.dhall comment.line.double-dash.dhall
# ^^^^^^^^ source.dhall comment.line.double-dash.dhall
>let user = "bill"
>let user = "bill"
#^^^ source.dhall meta.declaration.expression.let.dhall keyword.other.let.dhall
# ^ source.dhall meta.declaration.expression.let.dhall
# ^^^^ source.dhall meta.declaration.expression.let.dhall variable.other.constant.dhall
Expand All @@ -23,7 +23,6 @@
# ^ source.dhall meta.declaration.expression.let.dhall meta.declaration.foobar.dhall string.quoted.double.dhall
# ^^^^ source.dhall meta.declaration.expression.let.dhall meta.declaration.foobar.dhall string.quoted.double.dhall
# ^ source.dhall meta.declaration.expression.let.dhall meta.declaration.foobar.dhall string.quoted.double.dhall
# ^^ source.dhall meta.declaration.expression.let.dhall meta.declaration.foobar.dhall
>in { home = "/home/${user}"
#^^ source.dhall keyword.control.dhall
# ^^ source.dhall
Expand Down
81 changes: 53 additions & 28 deletions test/unit/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,136 +34,161 @@ describe('parseHeader', () => {
describe('parseScopeAssertion', () => {
it('should parse single ^ accent', () => {
expect(parseScopeAssertion(0, 1, "#^ source.dhall")).to.eql(
{
[{
"from": 1,
"scopes": [
"source.dhall"
],
exclude: [],
"to": 2
}
}]
)
});
it('should parse multiple ^^^^ accents', () => {
expect(parseScopeAssertion(0, 1, "# ^^^^^^ source.dhall")).to.eql(
{
[{
"from": 3,
"scopes": [
"source.dhall"
],
exclude: [],
"to": 9
}
}]
)
});

it('should parse multiple scopes', () => {
expect(parseScopeAssertion(0, 1, "# ^^ source.dhall variable.other.dhall")).to.eql(
{
[{
"from": 2,
"scopes": [
"source.dhall", "variable.other.dhall"
],
exclude: [],
"to": 4
}
}]
)
});

it('should not parse multiple accent groups', () => {
expect(parseScopeAssertion(0, 1, "# ^^ ^^^ source.dhall")).to.eq(undefined)
it('should parse multiple accent groups', () => {
expect(parseScopeAssertion(0, 1, "# ^^ ^^^ source.dhall")).to.deep.equal([
{
"exclude": [],
"from": 2,
"scopes": [
"source.dhall"
],
"to": 4
},
{
"exclude": [],
"from": 5,
"scopes": [
"source.dhall"
],
"to": 8
}
])
});

it('should parse single <- left arrow', () => {
expect(parseScopeAssertion(0, 1, "# <- source.dhall")).to.eql(
{
[{
"from": 0,
"scopes": [
"source.dhall"
],
exclude: [],
"to": 1
}
}]
)
});

it('should parse multi <~~--- left arrow with padding', () => {
expect(parseScopeAssertion(0, 1, "# <~~~--- source.dhall")).to.eql(
{
[{
"from": 3,
"scopes": [
"source.dhall"
],
exclude: [],
"to": 6
}
}]
)
});
it('should parse single ^ accent with exclusion', () => {
expect(parseScopeAssertion(0, 1, "#^ - source.dhall")).to.eql(
{
[{
"from": 1,
"scopes": [],
exclude: ["source.dhall"],
"to": 2
}
}]
)
});
it('should parse ^^^ accents with scopes and exclusion', () => {
expect(parseScopeAssertion(0, 1, "#^^^ foo.bar bar - source.dhall foo")).to.eql(
{
[{
"from": 1,
"scopes": ["foo.bar", "bar"],
exclude: ["source.dhall", "foo"],
"to": 4
}
}]
)
});
it('should parse <- with exclusion', () => {
expect(parseScopeAssertion(0, 1, "#<- - source.dhall")).to.eql(
{
[{
"from": 0,
"scopes": [],
exclude: ["source.dhall"],
"to": 1
}
}]
)
});
it('should parse <- with scopes and exclusion', () => {
expect(parseScopeAssertion(0, 1, "#<-- foo.bar bar - source.dhall foo")).to.eql(
{
[{
"from": 0,
"scopes": ["foo.bar", "bar"],
exclude: ["source.dhall", "foo"],
"to": 2
}
}]
)
});
it('should parse correctly treat spaces at the end with ^^', () => {
expect(parseScopeAssertion(0, 1, "#^^ foo - bar ")).to.eql(
{
[{
"from": 1,
"scopes": ["foo"],
exclude: ["bar"],
"to": 3
}
}]
)
});
it('should parse correctly treat spaces at the end with <- ', () => {
expect(parseScopeAssertion(0, 1, "#<-- foo ")).to.eql(
{
[{
"from": 0,
"scopes": ["foo"],
exclude: [],
"to": 2
}
}]
)
});
it('should ignore empty <- ', () => {
expect(parseScopeAssertion(0, 1, "#<-- - ")).to.eq(undefined)
it('should throw an error for an empty <- ', () => {
expect(() => parseScopeAssertion(0, 1, "#<-- - "))
.to
.throw('Inalid assertion at line 0:\n'
+ '#<-- - \n'
+ ' Missing both required and prohibited scopes')
});
it('should ignore empty ^ ', () => {
expect(parseScopeAssertion(0, 1, "# ^^^ ")).to.eq(undefined)
it('should throw an error on empty ^ ', () => {
expect(() => parseScopeAssertion(0, 1, "# ^^^ "))
.to
.throw('Inalid assertion at line 0:\n'
+ '# ^^^ \n'
+ ' Missing both required and prohibited scopes')
});
});

Expand Down
13 changes: 8 additions & 5 deletions testcase/misplaced.scopes.test.dhall
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
-- SYNTAX TEST "source.dhall"
-- SYNTAX TEST "source.dhall"
-- simple test


{- Don't repeat yourself!
Repetition is error-prone
TODO: 1. automate the end-to-end tests
2. somehow show that scopes are out of order!
-}


let user = "bill"
in { home = "/home/${user}"
-- <~~~~- keyword.operator.record.begin.dhall
, privateKey = "/home/${user}/id_ed25519xjjjjffffffffffffffjdkfjskfjkdjfjdfjfkdkfjsdkfsdflsfsdflsfjsdkflsdfjsf"
-- ^^^^^^^^^^ source.dhall meta.declaration.data.record.block.dhall variable.object.property.dhall
-- ^ punctuation.separator.dictionary.key-value.dhall source.dhall
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^ string.quoted.double.dhall source.dhall
-- ^^^^^^^^^^ source.dhall meta.declaration.data.record.block.dhall variable.object.property.dhall
-- ^ source.dhall punctuation.separator.dictionary.key-value.dhall
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^ source.dhall string.quoted.double.dhall
, publicKey = "/home/${user}/id_ed25519.pub"
-- ^^^^^^^ constant.other.placeholder.dhall
-- ^^^^ meta.label.dhall
-- ^^^^ meta.label.dhall
}
-- <- keyword.operator.record.end.dhall meta.declaration.data.record.block.dhall

Expand Down
Loading

0 comments on commit f6090e7

Please sign in to comment.