Skip to content

Commit

Permalink
Develop (#21)
Browse files Browse the repository at this point in the history
* Working on improving js bindings

* Writing unit tests

* Added some unit tests

* Need a better result component

* Finished adding some unit tests

* Removed wasm default feature

---------

Co-authored-by: matt <[email protected]>
  • Loading branch information
1BADragon and CedarMatt authored Sep 5, 2023
1 parent cd43bc7 commit b5cdedc
Show file tree
Hide file tree
Showing 22 changed files with 727 additions and 2,775 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ wasm-bindgen = { version = "0.2.87", optional = true}
console_error_panic_hook = { version = "0.1.7", optional = true }
serde-wasm-bindgen = { version = "0.5.0", optional = true }
js-sys = { version = "0.3.64", optional = true }
num = "0.4.1"
2,545 changes: 40 additions & 2,505 deletions examples/wasm/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@babel/core": "^7.21.8",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-react": "^7.18.6",
"@types/react": "^18.2.21",
"babel-loader": "^9.1.2",
"babel-preset-react": "^6.24.1",
"css-loader": "^6.7.3",
Expand Down
26 changes: 21 additions & 5 deletions examples/wasm/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import CelComponent from "./pages/CelComponent";
import { Card } from "@fluentui/react-components";
import init from "rscel";
import CelComponent from "./components/CelComponent";
import * as React from "react";
import { UnitTestsComponent } from "./components/UnitTests";
import { useEffect, useState } from "react";

export default function App() {
const [isInit, setIsInit] = useState<boolean>(false);

useEffect(() => {
init().then((_res: any) => {
setIsInit(true);
});
}, []);

if (!isInit) {
return <div>Loading...</div>;
}
return (
<Card style={{ height: "640px", width: "480px", margin: "auto" }}>
<CelComponent />
</Card>
<div style={{ display: "grid", gridTemplateColumns: "30% auto" }}>
<UnitTestsComponent />
<div style={{ height: "640px", width: "480px", marginLeft: "50px" }}>
<CelComponent />
</div>
</div>
);
}
File renamed without changes.
154 changes: 154 additions & 0 deletions examples/wasm/src/components/CelComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import * as React from "react";
import "./CelComponent.css";

import init, { cel_eval, cel_details } from "rscel";
import { useState, useEffect } from "react";

export default function CelComponent() {
const [errorMessage, setErrorMessage] = useState<string>("");
const [prog, setProg] = useState<string>("");
const [params, setParams] = useState<string[]>([]);
const [paramVals, setParamVals] = useState<any>({});
const [lastResult, setLastResult] = useState<any | undefined>(undefined);

const generateParams = (): JSX.Element[] => {
return params.map((val) => {
return (
<div key={`param-${val}`} style={{ display: "flex" }}>
<label>{val}</label>
<input
style={{ marginLeft: "auto" }}
onChange={(event) => {
setParamVals((old: any) => {
try {
let newObj = { ...old };
newObj[val] = JSON.parse(event.target.value, (_, val) => {
console.log(val);
return typeof val === "string" && val.endsWith("n")
? BigInt(val.slice(0, -1))
: val;
});
setErrorMessage("");
return newObj;
} catch (e) {
setErrorMessage(e.toString());
return old;
}
});
}}
/>
</div>
);
});
};

const renderResult = (currResult: any): JSX.Element => {
console.log("render", currResult, typeof currResult);
switch (typeof currResult) {
case "number":
return <label>{currResult.toString()}</label>;
case "bigint":
return <label>{currResult.toString()}</label>;
case "string":
return <label>{currResult}</label>;
case "object":
if (Array.isArray(currResult)) {
return (
<>
<label>[</label>
<div style={{ paddingLeft: "5px" }}>
{currResult.map((value, index) => (
<span key={index.toString()}>{renderResult(value)}</span>
))}
</div>
<label>]</label>
</>
);
} else {
return (
<>
<label>{"{"}</label>
<div style={{ paddingLeft: "5px" }}>
{Object.entries(currResult).map(([key, value], index) => {
return (
<span key={index.toString()}>
<label>{key}:</label>
{renderResult(value)}
</span>
);
})}
</div>
<label>{"}"}</label>
</>
);
}
}
};

return (
<div style={{ margin: "15px" }}>
<h4>RsCel Evaluater</h4>
<label>Program Source:</label>
<textarea
style={{ width: "100%", height: "100px" }}
onChange={(event) => {
setProg(event.target.value);
}}
/>
<div style={{ display: "flex", rowGap: "10px", justifyContent: "right" }}>
<button
onClick={() => {
const res = cel_details(prog);

if (res.success) {
console.log(res);
const details = res.details;
setParams(details.params);
setErrorMessage("");
setLastResult(undefined);
} else {
setErrorMessage(
res.error
? `${res.error.kind}: ${res.error.msg}`
: "Unknown error"
);
setLastResult(undefined);
}
}}
>
Analyze
</button>
<button
onClick={() => {
console.log(paramVals);
const result = cel_eval(prog, paramVals);
console.log(result);

if (result.success) {
setLastResult(result.result);
setErrorMessage("");
} else {
setErrorMessage(
result.error
? `${result.error.kind}: ${result.error.msg}`
: "Unknown error"
);
}
}}
>
Eval
</button>
</div>
<label>{errorMessage}</label>
<div style={{ marginTop: "40px" }}>{generateParams()}</div>
{lastResult && (
<>
<label key="label">Result:</label>
<div key="result" style={{ paddingLeft: "5px" }}>
{renderResult(lastResult)}
</div>
</>
)}
</div>
);
}
52 changes: 52 additions & 0 deletions examples/wasm/src/components/UnitTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as React from "react";
import { useEffect, useState } from "react";

export interface UnitTestProps {
name: string;
test: () => any;
expected: any;
}

export const UnitTest = (props: UnitTestProps) => {
const { name, test, expected } = props;

const [testPassed, setTestPassed] = useState<boolean>(false);
const [result, setResult] = useState<any>({});

const EPSILON = 0.0000001;

useEffect(() => {
const result = test();

if (result.success) {
if (typeof result.result === "number" && typeof expected === "number") {
setResult(result.result);
setTestPassed(Math.abs(result.result - expected) < EPSILON);
} else {
setTestPassed(result.result === expected);
}
} else {
setTestPassed(false);
}
}, []);

const renderPassFail = () => {
if (testPassed) {
return <label style={{ color: "green" }}>PASS</label>;
}

return (
<span>
<label style={{ color: "red" }}>FAIL</label>
<label>{`${result} != ${expected}`}</label>
</span>
);
};

return (
<div style={{ display: "grid", gridTemplateColumns: "30% auto" }}>
<label style={{ wordWrap: "normal" }}>{name}</label>
{renderPassFail()}
</div>
);
};
23 changes: 23 additions & 0 deletions examples/wasm/src/components/UnitTests.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as React from "react";

import { UnitTest } from "./UnitTest";
import { tests } from "./testCases";

export const UnitTestsComponent = () => {
return (
<div
style={{
width: "100%",
}}
>
{tests.map((value) => (
<UnitTest
key={`unittest-${value[0]}`}
name={value[0]}
test={value[1]}
expected={value[2]}
/>
))}
</div>
);
};
14 changes: 14 additions & 0 deletions examples/wasm/src/components/testCases.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { cel_eval } from "rscel";

export const tests: [string, () => any, any][] = [
["basic", () => cel_eval("3+3", {}), BigInt(6)],
["cel_int", () => cel_eval("3 + foo", { foo: { cel_int: 4.3 } }), BigInt(7)],
["cel_float", () => cel_eval("3.0 + foo", { foo: { cel_float: 2 } }), 5.0],
[
"cel_uint",
() => cel_eval("3u + foo", { foo: { cel_uint: 2.1 } }),
BigInt(5),
],
["float", () => cel_eval("3.2 + foo", { foo: 2.1 }), 5.3],
["int", () => cel_eval("3 + foo", { foo: 3 }), BigInt(6)],
];
99 changes: 0 additions & 99 deletions examples/wasm/src/pages/CelComponent.tsx

This file was deleted.

Loading

0 comments on commit b5cdedc

Please sign in to comment.