Skip to content

Commit

Permalink
codeblock + jsonata test expr
Browse files Browse the repository at this point in the history
  • Loading branch information
Geoffrey Hendrey committed Nov 4, 2023
1 parent 4802027 commit 4200b0d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Unlike an ordinary program, Stated templates can be kept "alive" indefinitely. A
causes change propagation throughout the DAG. Stated includes a node REPL, `stated.ts`, for testing Stated json templates, and a JS library for embedding stated
in applications. A typical REPL session consists of loading a template with the `init` command, viewing the computed
output with the `.out` command and then setting values with the `.set` command and observing the changed output.
```json
```json [false, false, "a=87 and e=42"]
falken$ stated
> .init -f "example/ex08.json"
{
Expand Down Expand Up @@ -399,7 +399,7 @@ The `!` symbol is used mark fields as temporary. The `!` can be used both as a p
to a key. Temporary fields are removed from the output.
Notice how /b and /c! are removed from the output. Also notice that when an expression like ```${`c!`.c1}``` refers to `c!`
that backtics must be used.
```json {"testWith":"tempVarsTest:}
```json
> .init -f "example/tempVars.json"
{
"a": 42,
Expand Down
63 changes: 48 additions & 15 deletions README.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import CliCore from './dist/src/CliCore.js';
import fs from 'fs';
import StatedREPL from './dist/src/StatedREPL.js';
import jsonata from "jsonata";

/**
* Regular expression for command extraction from README.md file. This program finds all the markup code blocks
Expand Down Expand Up @@ -49,35 +50,67 @@ import StatedREPL from './dist/src/StatedREPL.js';
* m: Multiline flag, to allow ^ and $ to match the start and end of lines, not just the start and end of the whole string.
*/
const markdownContent = fs.readFileSync("README.md", 'utf-8');
const commandRegex = /^> \.(?<command>.+[\r\n])((?<expectedResponse>(?:(?!^>|```)[\s\S])*))$/gm;;
const codeBlockRegex = /```(?<codeBlock>[\s\S]*?)```/g;
const jsonataExpressionsArrayRegex = /^[^\[]*(?<jsonataExpressionsArrayString>\s*\[.*?\]\s*)$/m
const commandRegex = /^> \.(?<command>.+[\r\n])((?<expectedResponse>(?:(?!^>|```)[\s\S])*))$/gm;
let match;
const cliCore = new CliCore();
const testData = [];

while ((match = commandRegex.exec(markdownContent)) !== null) {
const command = match.groups.command.trim();
const expectedResponseString = match.groups.expectedResponse.trim();
const args = command.split(' ');
while ((match = codeBlockRegex.exec(markdownContent)) !== null) {
const {codeBlock} = match.groups;
let _match = jsonataExpressionsArrayRegex.exec(codeBlock);
let jsonataExprArrayJson;
if(_match!==null){
const {jsonataExpressionsArrayString} = _match.groups;
if(jsonataExpressionsArrayString !== undefined){
jsonataExprArrayJson = JSON.parse(jsonataExpressionsArrayString);
}
}
let i=0;
while((_match = commandRegex.exec(codeBlock)) !== null){
const {command, expectedResponse} = _match.groups;
const expectedResponseString = _match.groups.expectedResponse.trim();
const args = command.trim().split(' ');

if (args.length > 0) {
const cmdName = args.shift();
const method = cliCore[cmdName];
if (args.length > 0) {
const cmdName = args.shift();
const method = cliCore[cmdName];

if (typeof method === 'function') {
testData.push([cmdName, args, expectedResponseString]);
} else {
throw Error(`Unknown command: .${cmdName}`);
if (typeof method === 'function') {
let jsonataExpr;
if(jsonataExprArrayJson !== undefined){
jsonataExpr = jsonataExprArrayJson[i];
}else{
jsonataExpr = false;
}
testData.push([cmdName, args, expectedResponse, jsonataExpr]);
} else {
throw Error(`Unknown command: .${cmdName}`);
}
}
i++;
}

}

testData.forEach(([cmdName, args, expectedResponseString], i) => {

testData.forEach(([cmdName, args, expectedResponseString, jsonataExpression], i) => {
test(`${cmdName} ${args.join(' ')}`, async () => {
const rest = args.join(" ");
const resp = await cliCore[cmdName].apply(cliCore, [rest]);
const respNormalized = JSON.parse(StatedREPL.stringify(resp));
const _expected = JSON.parse(expectedResponseString);
expect(respNormalized).toEqual(_expected);
if(jsonataExpression){ //if we have an optional jsonata expression specified after the codeblock, likje ````json <optionaJsonataExpression>
const compiledExpr = jsonata(jsonataExpression);
expect(await compiledExpr.evaluate(respNormalized)).toBe(true);
}else {
if(expectedResponseString){
const _expected = JSON.parse(expectedResponseString);
expect(respNormalized).toEqual(_expected);
}else{
expect(respNormalized).toBeDefined();
}
}
}, 30000); // set timeout to 10 seconds for each test since in the readme we call web apis
});

0 comments on commit 4200b0d

Please sign in to comment.