-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from dyne/sf/plugin
feat(fs)!: parse ignored statements individually
- Loading branch information
Showing
6 changed files
with
183 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,62 @@ | ||
import { lex } from './lexer'; | ||
import { ThenI, SaveThe, IntoTheFile } from './tokens'; | ||
import { Then, I, SaveThe, IntoTheFile } from './tokens'; | ||
|
||
import { Identifier } from '@slangroom/shared/tokens'; | ||
import { getIgnoredStatements } from '@slangroom/ignored'; | ||
|
||
test('lexing works', async () => { | ||
// Given I have a contract with filesystem statements in it | ||
const contract = `Rule unknown ignore | ||
Given I have a 'string' named 'stringToWrite' | ||
and I have a 'string' named 'nameOfTheFile' | ||
Given I have a 'string' named 'stringToWrite0' | ||
and I have a 'string' named 'nameOfTheFile0' | ||
and I have a 'string' named 'stringToWrite1' | ||
and I have a 'string' named 'nameOfTheFile1' | ||
Then I save the 'stringToWrite' into the file 'nameOfTheFile' | ||
Then I save the 'stringToWrite0' into the file 'nameOfTheFile0' | ||
and I save the 'stringToWrite1' into the file 'nameOfTheFile1' | ||
`; | ||
// When I lex it | ||
const lexed = await lex(contract, { data: { stringToWrite: 'foo', nameOfTheFile: 'bar' } }); | ||
// Then the result must have no errors | ||
expect(lexed.errors).toHaveLength(0); | ||
// and it must have 5 tokens | ||
expect(lexed.tokens).toHaveLength(5); | ||
// When I get the ignored statements of it | ||
const ignoreds = await getIgnoredStatements(contract, { | ||
data: { | ||
stringToWrite0: 'foo0', nameOfTheFile0: 'bar0', | ||
stringToWrite1: 'foo1', nameOfTheFile1: 'bar1', | ||
}, | ||
}); | ||
// and I lex each of them | ||
const lexeds = ignoreds.map((x) => lex(x)); | ||
// Then the result must contain 2 items | ||
expect(lexeds).toHaveLength(2); | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
|
||
// When I get the first one | ||
const first = lexeds[0]!; | ||
// Then it must have no errors | ||
expect(first.errors).toHaveLength(0); | ||
// and it must have 6 tokens | ||
expect(first.tokens).toHaveLength(6); | ||
// and those tokens must be these: | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
expect(first.tokens[0]!.tokenType).toStrictEqual(Then); | ||
expect(first.tokens[1]!.tokenType).toStrictEqual(I); | ||
expect(first.tokens[2]!.tokenType).toStrictEqual(SaveThe); | ||
expect(first.tokens[3]!.tokenType).toStrictEqual(Identifier); | ||
expect(first.tokens[4]!.tokenType).toStrictEqual(IntoTheFile); | ||
expect(first.tokens[5]!.tokenType).toStrictEqual(Identifier); | ||
/* eslint-enable */ | ||
|
||
// When I get the second one | ||
const second = lexeds[0]!; | ||
// Then it must have no errors | ||
expect(second.errors).toHaveLength(0); | ||
// and it must have 6 tokens | ||
expect(second.tokens).toHaveLength(6); | ||
// and those tokens must be these: | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
expect(lexed.tokens[0]!.tokenType).toStrictEqual(ThenI); | ||
expect(lexed.tokens[1]!.tokenType).toStrictEqual(SaveThe); | ||
expect(lexed.tokens[2]!.tokenType).toStrictEqual(Identifier); | ||
expect(lexed.tokens[3]!.tokenType).toStrictEqual(IntoTheFile); | ||
expect(lexed.tokens[4]!.tokenType).toStrictEqual(Identifier); | ||
expect(second.tokens[0]!.tokenType).toStrictEqual(Then); | ||
expect(second.tokens[1]!.tokenType).toStrictEqual(I); | ||
expect(second.tokens[2]!.tokenType).toStrictEqual(SaveThe); | ||
expect(second.tokens[3]!.tokenType).toStrictEqual(Identifier); | ||
expect(second.tokens[4]!.tokenType).toStrictEqual(IntoTheFile); | ||
expect(second.tokens[5]!.tokenType).toStrictEqual(Identifier); | ||
/* eslint-enable */ | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,13 @@ | ||
import { vocab } from './tokens'; | ||
|
||
import { type ZenroomParams } from '@slangroom/shared'; | ||
import { getIgnoredStatements } from '@slangroom/ignored'; | ||
import { Lexer } from '@slangroom/deps/chevrotain'; | ||
|
||
const FsLexer = new Lexer(vocab); | ||
|
||
/** | ||
* Lexes the input text for filesystem statements. | ||
* Lexes the given statement for filesystems statements. | ||
* | ||
* @param contract the zencode contract to be lexed. | ||
* @returns the lexed result. | ||
*/ | ||
export const lex = async (contract: string, params?: ZenroomParams) => { | ||
const ignored = await getIgnoredStatements(contract, params); | ||
return FsLexer.tokenize(ignored.join('\n')); | ||
}; | ||
* @param statement is the statement ignored by Zenroom. | ||
* @returns the tokens of the lexed result. | ||
**/ | ||
export const lex = (statement: string) => FsLexer.tokenize(statement); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,100 @@ | ||
import { visit } from './visitor'; | ||
|
||
test('ast is correct', async () => { | ||
// Given I have a contract with filesystem statements in it | ||
import { getIgnoredStatements } from '@slangroom/ignored'; | ||
|
||
test('ast is correct with one statement', async () => { | ||
// Given I have a contract with one filesystems statement in it | ||
const contract = `Rule unknown ignore | ||
Given I have a 'string' named 'stringToWrite' | ||
and I have a 'string' named 'nameOfTheFile' | ||
Then I save the 'stringToWrite' into the file 'nameOfTheFile' | ||
`; | ||
// When I generate ast of the contract | ||
const data = { | ||
stringToWrite: 'hello world', | ||
nameOfTheFile: 'hello-world.txt', | ||
}; | ||
const ast = await visit(contract, { data: data }); | ||
// Then the content must be "stringToWrite" | ||
// When I get the ignored statements of it | ||
const ignoreds = await getIgnoredStatements(contract, { | ||
data: data, | ||
}); | ||
// and I generate AST of each of them | ||
const asts = ignoreds.map((x) => visit(x)); | ||
// Then the result must contain only one item | ||
expect(asts).toHaveLength(1); | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const ast = asts[0]!; | ||
// and its content must be "stringToWrite" | ||
expect(ast.content).toStrictEqual('stringToWrite'); | ||
// and the filename must be "nameOfTheFile" | ||
// and its filename must be "nameOfTheFile" | ||
expect(ast.filename).toStrictEqual('nameOfTheFile'); | ||
// and the value indexed by the content in data must be "hello world" | ||
expect(data[ast.content as 'stringToWrite']).toStrictEqual('hello world'); | ||
// and the value indexed by the filename in data must be "hello-world.txt" | ||
expect(data[ast.filename as 'nameOfTheFile']).toStrictEqual('hello-world.txt'); | ||
// and the value indexed by its content in data must be data's stringToWrite | ||
expect(data[ast.content as 'stringToWrite']).toStrictEqual(data.stringToWrite); | ||
// and the value indexed by its filename in data must be data's nameOfTheFile | ||
expect(data[ast.filename as 'nameOfTheFile']).toStrictEqual(data.nameOfTheFile); | ||
}); | ||
|
||
test('ast is correct with multiple statements', async () => { | ||
// Given I have a contract with multiple filesystems statements in it | ||
const contract = `Rule unknown ignore | ||
Given I have a 'string' named 'stringToWrite0' | ||
and I have a 'string' named 'nameOfTheFile0' | ||
and I have a 'string' named 'stringToWrite1' | ||
and I have a 'string' named 'nameOfTheFile1' | ||
and I have a 'string' named 'stringToWrite2' | ||
and I have a 'string' named 'nameOfTheFile2' | ||
Then I save the 'stringToWrite0' into the file 'nameOfTheFile0' | ||
and I save the 'stringToWrite1' into the file 'nameOfTheFile1' | ||
and I save the 'stringToWrite2' into the file 'nameOfTheFile2' | ||
`; | ||
const data = { | ||
stringToWrite0: 'hello world0', | ||
nameOfTheFile0: 'hello-world0.txt', | ||
stringToWrite1: 'hello world1', | ||
nameOfTheFile1: 'hello-world1.txt', | ||
stringToWrite2: 'hello world2', | ||
nameOfTheFile2: 'hello-world2.txt', | ||
}; | ||
// When I get the ignored statements of it | ||
const ignoreds = await getIgnoredStatements(contract, { | ||
data: data, | ||
}); | ||
// and I generate AST of each of them | ||
const asts = ignoreds.map((x) => visit(x)); | ||
// Then the result must contain 3 items | ||
expect(asts).toHaveLength(3); | ||
// and I get the first one | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const first = asts[0]!; | ||
// and the its content must be "stringToWrite0" | ||
expect(first.content).toStrictEqual('stringToWrite0'); | ||
// and the its filename must be "nameOfTheFile" | ||
expect(first.filename).toStrictEqual('nameOfTheFile0'); | ||
// and the value indexed by its content in data must be data's stringToWrite0 | ||
expect(data[first.content as 'stringToWrite0']).toStrictEqual(data.stringToWrite0); | ||
// and the value indexed by its filename in data must be data's nameOfTheFile0 | ||
expect(data[first.filename as 'nameOfTheFile0']).toStrictEqual(data.nameOfTheFile0); | ||
// and I get the second one | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const second = asts[1]!; | ||
// and the its content must be "stringToWrite0" | ||
expect(second.content).toStrictEqual('stringToWrite1'); | ||
// and the its filename must be "nameOfTheFile" | ||
expect(second.filename).toStrictEqual('nameOfTheFile1'); | ||
// and the value indexed by its content in data must be data's stringToWrite1 | ||
expect(data[second.content as 'stringToWrite1']).toStrictEqual(data.stringToWrite1); | ||
// and the value indexed by its filename in data must be data's nameOfTheFile1 | ||
expect(data[second.filename as 'nameOfTheFile1']).toStrictEqual(data.nameOfTheFile1); | ||
// and I get the third one | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const third = asts[2]!; | ||
// and the its content must be "stringToWrite2" | ||
expect(third.content).toStrictEqual('stringToWrite2'); | ||
// and the its filename must be "nameOfTheFile" | ||
expect(third.filename).toStrictEqual('nameOfTheFile2'); | ||
// and the value indexed by its content in data must be data's stringToWrite2 | ||
expect(data[third.content as 'stringToWrite2']).toStrictEqual(data.stringToWrite2); | ||
// and the value indexed by its filename in data must be data's nameOfTheFile2 | ||
expect(data[third.filename as 'nameOfTheFile2']).toStrictEqual(data.nameOfTheFile2); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters