Skip to content

Commit

Permalink
tests done
Browse files Browse the repository at this point in the history
  • Loading branch information
M-Kusumgar committed Dec 19, 2024
1 parent 4534546 commit 7d35c64
Show file tree
Hide file tree
Showing 16 changed files with 487 additions and 175 deletions.
43 changes: 43 additions & 0 deletions app/server/src/static-site-builder/builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import path from "path";
import fs from "fs";
import { readFile } from "../configReader";
import axios from "axios";

export const buildWodinStaticSite = async (configPath: string, destPath: string) => {
const storesPath = path.resolve(configPath, "stores")
const stores = fs.readdirSync(storesPath, { recursive: false }) as string[];

// bootstrapping and making sure the folder structure is correct
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}
const destStoresPath = path.resolve(destPath, "stores");
if (fs.existsSync(destStoresPath)) {
fs.rmSync(destStoresPath, { recursive: true });
}
fs.mkdirSync(destStoresPath);

// copy in their config specific files (assets to come soon)
fs.cpSync(path.resolve(configPath, "index.html"), path.resolve(destPath, "index.html"));

// get runners
const runnerOdeResponse = await axios.get("http://localhost:8001/support/runner-ode");
fs.writeFileSync(path.resolve(destStoresPath, "runnerOde.js"), runnerOdeResponse.data.data);
const runnerDiscreteResponse = await axios.get("http://localhost:8001/support/runner-discrete");
fs.writeFileSync(path.resolve(destStoresPath, "runnerDiscrete.js"), runnerDiscreteResponse.data.data);

// make folder per store with config.json (their config + default code) and
// model.json (model response from odin.api)
stores.forEach(async store => {
const destStorePath = path.resolve(destStoresPath, store);
fs.mkdirSync(destStorePath);
const model = readFile(path.resolve(storesPath, store, "model.R")).split("\n");

const config = JSON.parse(readFile(path.resolve(storesPath, store, "config.json"))) as { appType: string };
fs.writeFileSync(path.resolve(destStorePath, "config.json"), JSON.stringify({ ...config, defaultCode: model }));

const timeType = config.appType === "stochastic" ? "discrete" : "continuous";
const modelResponse = await axios.post("http://localhost:8001/compile", { model, requirements: { timeType } });
fs.writeFileSync(path.resolve(destStorePath, `model.json`), JSON.stringify(modelResponse.data.data));
});
};
48 changes: 2 additions & 46 deletions app/server/src/static-site-builder/wodinBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,6 @@
import path from "path";
import fs from "fs";
import { readFile } from "../configReader";
import axios from "axios";
import { processArgs } from "./args";

const mkdirForce = (path: string) => {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
};
import { buildWodinStaticSite } from "./builder";

const { configPath, destPath } = processArgs();

const storesPath = path.resolve(configPath, "stores")
const stores = fs.readdirSync(storesPath, { recursive: false }) as string[];

mkdirForce(destPath);
const destStoresPath = path.resolve(destPath, "stores");
if (fs.existsSync(destStoresPath)) {
fs.rmSync(destStoresPath, { recursive: true });
}
fs.mkdirSync(destStoresPath);

fs.cpSync(path.resolve(configPath, "index.html"), path.resolve(destPath, "index.html"));

const getRunners = async () => {
const runnerOdeResponse = await axios.get("http://localhost:8001/support/runner-ode");
fs.writeFileSync(path.resolve(destStoresPath, "runnerOde.js"), runnerOdeResponse.data.data);

const runnerDiscreteResponse = await axios.get("http://localhost:8001/support/runner-discrete");
fs.writeFileSync(path.resolve(destStoresPath, "runnerDiscrete.js"), runnerDiscreteResponse.data.data);
}
getRunners();

stores.forEach(async store => {
const destStorePath = path.resolve(destStoresPath, store);
fs.mkdirSync(destStorePath);

const model = readFile(path.resolve(storesPath, store, "model.R")).split("\n");

const config = JSON.parse(readFile(path.resolve(storesPath, store, "config.json"))) as { appType: string };
fs.writeFileSync(path.resolve(destStorePath, "config.json"), JSON.stringify({ ...config, defaultCode: model }));

const modelResponse = await axios.post("http://localhost:8001/compile", {
model,
requirements: { timeType: config.appType === "stochastic" ? "discrete" : "continuous" }
});
fs.writeFileSync(path.resolve(destStorePath, `model.json`), JSON.stringify(modelResponse.data.data));
});
buildWodinStaticSite(configPath, destPath);
29 changes: 29 additions & 0 deletions app/server/tests/static-site-builder/args.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { processArgs } from "../../src/static-site-builder/args";

describe("args", () => {
const realArgs = process.argv;
afterEach(() => {
process.argv = realArgs;
});

const builderPath = "/builder",
cfgPath = "/configPath",
destPath = "/destPath";

it("throws error if no config path or dest path arg", () => {
const argv = ["node", builderPath];
expect(() => { processArgs(argv); })
.toThrow("Usage:");

const argv1 = ["node", builderPath, cfgPath];
expect(() => { processArgs(argv1); })
.toThrow("Usage:");
});

it("returns config path and dest path", () => {
const argv = ["node", builderPath, cfgPath, destPath];
const args = processArgs(argv);
expect(args.configPath).toBe(cfgPath);
expect(args.destPath).toBe(destPath);
});
});
90 changes: 90 additions & 0 deletions app/server/tests/static-site-builder/builder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import path from "path";
import fs from "fs";
import { tmpdirTest } from "./tempDirTestHelper"
import { buildWodinStaticSite } from "../../src/static-site-builder/builder"

const buildSite = async (tmpdir: string) => {
await buildWodinStaticSite("../../config-static", tmpdir);
}

const {
mockRunnerOde, mockRunnerDiscrete,
mockModel, mockGet, mockPost
} = vi.hoisted(() => {
const mockRunnerOde = "var odinRunnerOde;";
const mockRunnerDiscrete = "var odinRunnerDiscrete;";
const mockModel = "class odinModel {};";
const mockGet = vi.fn().mockImplementation((url: string) => {
if (url === "http://localhost:8001/support/runner-ode") {
return { data: { data: mockRunnerOde } };
} else if (url === "http://localhost:8001/support/runner-discrete") {
return { data: { data: mockRunnerDiscrete } };
}
});
const mockPost = vi.fn().mockImplementation((url: string) => {
if (url === "http://localhost:8001/compile") {
return { data: { data: mockModel } };
}
});
return {
mockRunnerOde, mockRunnerDiscrete,
mockModel, mockGet, mockPost
};
});

vi.mock("axios", () => {
return {
default: {
get: mockGet,
post: mockPost
}
}
});

const p = path.resolve;

const expectPath = (...paths: string[]) => {
expect(fs.existsSync(p(...paths))).toBe(true);
};

const expectPathContent = (content: string, ...paths: string[]) => {
expect(fs.readFileSync(p(...paths)).toString()).toBe(content);
}

const expectPathContentContains = (content: string, ...paths: string[]) => {
expect(fs.readFileSync(p(...paths)).toString()).toContain(content);
}

describe("Wodin builder", () => {
tmpdirTest("creates dest dir if it doesn't exist", async ({ tmpdir }) => {
fs.rmdirSync(tmpdir);
await buildSite(tmpdir);
expectPath(tmpdir);
});

tmpdirTest("works as expected", async ({ tmpdir }) => {
const storesPath = p(tmpdir, "stores");
await buildSite(tmpdir);

expectPath(tmpdir, "index.html");

expectPath(storesPath, "runnerOde.js");
expectPathContent(mockRunnerOde, storesPath, "runnerOde.js");
expectPath(storesPath, "runnerDiscrete.js");
expectPathContent(mockRunnerDiscrete, storesPath, "runnerDiscrete.js");

expectPath(storesPath, "basic", "model.json");
expectPathContentContains(mockModel, storesPath, "basic", "model.json");
expectPath(storesPath, "basic", "config.json");
});

tmpdirTest("overwrites existing stores folder", async ({ tmpdir }) => {
const storesPath = p(tmpdir, "stores");
fs.mkdirSync(storesPath);
fs.writeFileSync(p(storesPath, "trash.txt"), "whats up");

await buildSite(tmpdir);

expect(fs.existsSync(p(storesPath, "trash.txt"))).toBe(false)
});
})
22 changes: 22 additions & 0 deletions app/server/tests/static-site-builder/tempDirTestHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { test } from "vitest";
import os from "node:os";
import path from "path";
import fs from "fs";

type TmpDirTestFixture = { tmpdir: string; }

const createTempDir = () => {
const ostmpdir = os.tmpdir();
const tmpdir = path.resolve(ostmpdir, "static-site-builder-tests-");
return fs.mkdtempSync(tmpdir);
};

export const tmpdirTest = test.extend<TmpDirTestFixture>({
// eslint-disable-next-line no-empty-pattern
tmpdir: async ({}, use) => {
const dir = createTempDir();
await use(dir);

fs.rmSync(dir, { recursive: true })
}
});
2 changes: 1 addition & 1 deletion app/server/vitest/vitest.unit.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default mergeConfig(
coverage: {
provider: "istanbul",
include: ["src"],
exclude: ["**/tests/**", "src/server/server.ts"]
exclude: ["**/tests/**", "src/server/server.ts", "src/static-site-builder/wodinBuilder.ts"]
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion app/static/src/externalScriptSrc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const externalScripts = [
export const externalScripts = [
"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"
];

Expand Down
18 changes: 0 additions & 18 deletions app/static/src/mainUtils.ts

This file was deleted.

106 changes: 0 additions & 106 deletions app/static/src/wodin-static.ts

This file was deleted.

2 changes: 1 addition & 1 deletion app/static/src/wodin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "./assets/fontawesome.css";
import "./scss/style.scss"
import help from "./directives/help";
import App from "./components/App.vue";
import { getStoreOptions } from "./mainUtils";
import { getStoreOptions } from "./wodinStaticUtils";
import { Store, StoreOptions } from "vuex";
import { mountScriptTags } from "./externalScriptSrc";

Expand Down
Loading

0 comments on commit 7d35c64

Please sign in to comment.