Skip to content

Commit

Permalink
Merge pull request #10 from dyne/sf/improvements
Browse files Browse the repository at this point in the history
Improvements (TM)
  • Loading branch information
denizenging authored Jul 10, 2023
2 parents d4fa708 + abab56a commit d1603a9
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 37 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@ on:
push:
branches:
- main

permissions:
contents: write

jobs:
deploy_pages:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v3

- uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'pnpm'

- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 8
name: Install pnpm
with:
version: 8

- run: |
pnpm install
pnpm docs
Expand Down
2 changes: 1 addition & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type JestConfigWithTsJest } from 'ts-jest';
import type { JestConfigWithTsJest } from 'ts-jest';

export default <JestConfigWithTsJest>{
transform: { '^.+\\.ts$': ['ts-jest', { useESM: true }] },
Expand Down
2 changes: 1 addition & 1 deletion pkg/fs/lexer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ThenI, SaveThe, IntoTheFile } from './tokens';

import { Identifier } from '@slangroom/shared/tokens';

test('that lexing works', async () => {
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'
Expand Down
4 changes: 2 additions & 2 deletions pkg/fs/parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IntoTheFile, SaveThe, ThenI, vocab } from './tokens';
import { lex } from './lexer';

import { CstParser, IToken } from '@slangroom/deps/chevrotain';
import { CstParser, type IToken } from '@slangroom/deps/chevrotain';
import { Identifier } from '@slangroom/shared/tokens';
import { ZenroomParams } from '@slangroom/shared/zenroom';

Expand All @@ -19,7 +19,7 @@ class Parser extends CstParser {
this.performSelfAnalysis();
}

public fileOverrideStatement = this.RULE('fileOverrideStatement', () => {
fileOverrideStatement = this.RULE('fileOverrideStatement', () => {
this.CONSUME(ThenI);
this.CONSUME(SaveThe);
this.CONSUME(Identifier, { LABEL: 'content' });
Expand Down
3 changes: 2 additions & 1 deletion pkg/fs/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const SaveThe = createToken({
pattern: /save the/,
});

/** * The "into the file" statement, used to indicate the file to which to
/**
* The "into the file" statement, used to indicate the file to which to
* write.
*/
export const IntoTheFile = createToken({
Expand Down
21 changes: 15 additions & 6 deletions pkg/fs/visitor.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { visit } from './visitor';

test('that', async () => {
test('ast is correct', 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'
Then I save the 'stringToWrite' into the file 'nameOfTheFile'
`;
await visit(contract, {
data: { stringToWrite: 'hello world', nameOfTheFile: 'hello-world.txt' },
});

expect(true).toStrictEqual(true);
// 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"
expect(ast.content).toStrictEqual('stringToWrite');
// and the 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');
});
8 changes: 4 additions & 4 deletions pkg/fs/visitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BaseFsVisitor, parse, type FileOverrideStatementCtx } from './parser';

import { type ZenroomParams } from '@slangroom/shared';
import { type CstNode } from '@slangroom/deps/chevrotain';
import type { ZenroomParams } from '@slangroom/shared';
import type { CstNode } from '@slangroom/deps/chevrotain';

export type FileOverrideStatement = {
content: string;
Expand All @@ -23,8 +23,8 @@ class Visitor extends BaseFsVisitor {
const content = ctx.content[0].image;
const filename = ctx.filename[0].image;
return {
content: content,
filename: filename,
content: content.slice(1, -1),
filename: filename.slice(1, -1),
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/ignored/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getIgnoredStatements } from './index';

test("that zenroom ignores statements it doesn't know in general", async () => {
test("zenroom ignores statements it doesn't know in general", async () => {
// Given I have a contract with a general rule unknown statemets in it
const uknowns = [
'When I test the rule with a statement that does not exist 1',
Expand All @@ -21,7 +21,7 @@ Then print the data
expect(result).toStrictEqual(uknowns);
});

test("that zenroom doesn't ignore ecdh but ignores restroom statements", async () => {
test("zenroom doesn't ignore ecdh but ignores restroom statements", async () => {
// Given I have a contract with ecdh and restroom statements
const contract = `# Always use 'Rule caller restroom-mw' when using Restroom
Rule caller restroom-mw
Expand Down
2 changes: 1 addition & 1 deletion pkg/ignored/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { vocab } from './tokens';

import { type ZenroomParams, zencodeExec } from '@slangroom/shared';
import { zencodeExec, type ZenroomParams } from '@slangroom/shared';
import { Lexer } from '@slangroom/deps/chevrotain';

const IgnoredLexer = new Lexer(vocab);
Expand Down
15 changes: 7 additions & 8 deletions pkg/ignored/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { createToken, CustomPatternMatcherFunc } from '@slangroom/deps/chevrotai
/*
* Prevent regex-ast annoing warnings
* https://github.com/Chevrotain/chevrotain/issues/1670#issuecomment-1001673472
* */
*/
const wrap = (regex: RegExp): CustomPatternMatcherFunc => {
return (text: string, offset: number): RegExpExecArray | null => {
const re = new RegExp(regex, 'y');
re.lastIndex = offset
return re.exec(text)
}
}

return (text: string, offset: number): RegExpExecArray | null => {
const re = new RegExp(regex, 'y');
re.lastIndex = offset;
return re.exec(text);
};
};

/**
* Statements ignored by Zenroom.
Expand Down
6 changes: 3 additions & 3 deletions pkg/shared/tokens.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ test('that identifiers are identified correctly', () => {
'four' # blanks here and there
'five' # mix of blanks and tabs
`;
// When I lex the it
// When I lex it
const lexed = lex(contract);
// Then I must have no errors
expect(lexed.errors).toHaveLength(0);
Expand Down Expand Up @@ -58,7 +58,7 @@ test('that identifiers are identified correctly', () => {
/* eslint-enable */
});

test('that non-matcheds error out', () => {
test('non-matcheds error out', () => {
// Given I have a broken contract
const contract = `broken contract`;
// When I lex it
Expand All @@ -82,7 +82,7 @@ test('that non-matcheds error out', () => {
]);
});

test('that tokens are skipped correctly', () => {
test('tokens are skipped correctly', () => {
// Given I have a contract with several ignored and an identifier tokens
const contract = "given I am 'alice'";
// When I lex it
Expand Down
26 changes: 24 additions & 2 deletions pkg/shared/zenroom.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { convZenParams } from './zenroom';
import { convZenParams, zencodeExec, ZenroomError } from './zenroom';

test('that convZenParams() works', () => {
test('convZenParams() works', () => {
// Since TS already covers our butts regarding type checks, we just
// need to convice the coverage here that all the code paths are
// taken.
Expand Down Expand Up @@ -44,3 +44,25 @@ test('that convZenParams() works', () => {
expect(result).toStrictEqual({ data: JSON.stringify(data), keys: JSON.stringify(keys) });
}
});

describe('zencode()', () => {
test("doesn't throw with valid input", async () => {
// Given I have a valid contract
const contract = `Given I have nothing
Then I print string 'I love you'
`;
// When I execute the contract
const promise = zencodeExec(contract);
// Then it must not throw any errors
await expect(promise).resolves.toBeTruthy();
});

test('throws with invalid input', async () => {
// Given I have an invalid contract
const contract = "I'm invalid.";
// When I execute the contract
const promise = zencodeExec(contract);
// Then it must throw some errors
await expect(promise).rejects.toThrow(ZenroomError);
});
});
19 changes: 18 additions & 1 deletion pkg/shared/zenroom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ export type ZenroomResult = {
logs: string;
};

/**
* Error thrown by [zenroomExec] if contract execution somehow fails.
*/
export class ZenroomError extends Error {
constructor(logs: string) {
super(logs);
this.name = 'ZenroomError';
}
}

/**
* Zenroom parameters suitable for zencode_exec() (after each value's
* been piped to JSON.stringify()).
Expand Down Expand Up @@ -51,8 +61,15 @@ export const convZenParams = (params?: ZenroomParams): ZenroomStringParams => {
* @param contract is a zencode contract.
* @param params is parameters to Zenroom.
* @returns the output of Zenroom.
* @throws {ZenroomError} if execution of a contract fails.
*/
export const zencodeExec = async (
contract: string,
params?: ZenroomParams
): Promise<ZenroomResult> => await zencode_exec(contract, convZenParams(params));
): Promise<ZenroomResult> => {
try {
return await zencode_exec(contract, convZenParams(params));
} catch (e) {
throw new ZenroomError(e.logs);
}
};
2 changes: 1 addition & 1 deletion pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
packages:
- 'pkg/*'
- pkg/*

0 comments on commit d1603a9

Please sign in to comment.