Skip to content

Commit

Permalink
Add CLI for MemoryViz (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahsonder authored Jun 19, 2024
1 parent 4b0decb commit da9c3d5
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 7 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ jobs:
run: npm ci
- name: Run prettier
run: npx prettier . --write
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Apply formatting changes
branch: ${{ github.head_ref }}
# - name: Commit changes
# uses: stefanzweifel/git-auto-commit-action@v4
# with:
# commit_message: Apply formatting changes
# branch: ${{ github.head_ref }}
jest:
if: github.event.pull_request.draft == false
runs-on: ubuntu-22.04
Expand All @@ -39,6 +39,8 @@ jobs:
cache: npm
- name: Install npm packages
run: npm ci
- name: Compile JavaScript assets
run: npm run build --workspace=memory-viz
- name: Run jest tests
run: npm run test-cov
- name: Coveralls (jest)
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### ✨ Enhancements

- Created a CLI for MemoryViz.

### 🐛 Bug fixes

- Fixed a bug where box fill colours would cover box text, and changed the implementation of `hide` style option.
- Removed double quotes when rendering objects of type `None`.

### 📚 Documentation and demo website changes

- Added documentation page for the MemoryViz CLI.

### 🔧 Internal changes

- Added a changelog and pull request template.
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ produces a file `simple_demo.svg` that looks like the following:

For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/) and [demo](https://www.cs.toronto.edu/~david/memory-viz/demo/).

### MemoryViz CLI

To run MemoryViz from your terminal, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).

## Developers

### Installation
Expand Down
21 changes: 21 additions & 0 deletions docs/docs/06-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: MemoryViz CLI
---

# MemoryViz CLI

You can run MemoryViz straight from your terminal!

## Input

To run the MemoryViz CLI, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. If the file content is not compatible with MemoryViz, an error will be thrown.

## Output

The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. The name of the SVG will be the same as that of the inputted file (i.e., if the inputted file is `david-is-cool.json`, the output will be `david-is-cool.svg`).
10 changes: 10 additions & 0 deletions memory-viz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ produces a file `simple_demo.svg` that looks like the following:

For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/) and [demo](https://www.cs.toronto.edu/~david/memory-viz/demo/).

### MemoryViz CLI

To run MemoryViz from your terminal, run:

```console
$ npx memory-viz <path-to-file>
```

replacing `<path-to-file>` with the path to a file containing MemoryViz-compatible JSON. The output is an SVG image generated by MemoryViz and the image is saved in the current working directory. For more information, check out the project [documentation website](https://www.cs.toronto.edu/~david/memory-viz/docs/cli).

## Developers

### Installation
Expand Down
55 changes: 55 additions & 0 deletions memory-viz/bin/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env node

const fs = require("fs");
const path = require("path");
const { draw } = require("memory-viz");

// Check for correct number of arguments
if (process.argv.length !== 3) {
console.error(
"Error: wrong number of arguments.\nUsage: memory-viz <path-to-file>"
);
process.exit(1);
}
const filePath = process.argv[2];
const absolutePath = path.resolve(process.cwd(), filePath);

// Checks if absolutePath exists and that it is a JSON file
let fileContent;
if (!fs.existsSync(absolutePath)) {
console.error(`Error: File ${absolutePath} does not exist.`);
process.exit(1);
} else {
fileContent = fs.readFileSync(absolutePath, "utf8");
}

let data;
try {
data = JSON.parse(fileContent);
} catch (err) {
console.error(`Error: Invalid JSON\n${err.message}.`);
process.exit(1);
}

let m;
try {
// TODO: Replace width and seed with command-line arguments
m = draw(data, true, {
width: 1300,
roughjs_config: { options: { seed: 12345 } },
});
} catch (err) {
console.error(
`This is valid JSON but not valid Memory Models JSON.` +
`Please refer to the repo for more details.`
);
process.exit(1);
}

const outputName = path.parse(filePath).name + ".svg";
try {
m.save(outputName);
} catch (err) {
console.error(`Error: ${err.message}`);
process.exit(1);
}
3 changes: 3 additions & 0 deletions memory-viz/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"bugs": {
"url": "https://github.com/david-yz-liu/memory-viz/issues"
},
"bin": {
"memory-viz": "bin/cli.js"
},
"dependencies": {
"@xmldom/xmldom": "^0.8.6",
"deepmerge": "^4.3.1",
Expand Down
3 changes: 3 additions & 0 deletions memory-viz/src/tests/__snapshots__/cli.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`memory-viz cli should produce an svg that matches snapshot 1`] = `"<svg width="1300" height="292" xmlns="http://www.w3.org/2000/svg"><g><path d="M50.03387502096594 24.981137046590447 L249.8663759674877 25.23432659842074 L249.97923236750066 154.9256116244942 L50.3987259592861 154.70078069902956" stroke="none" stroke-width="0" fill="yellow"/><path d="M49.80511280181001 24.848283371017935 C101.21462960343666 24.957142048644016, 152.4283732904477 25.27468179969294, 249.8333185797511 24.888723166230132 M50.04025084290156 25.084566500893157 C127.64847626362833 25.010388792416617, 205.73433892848544 25.26086524016505, 249.87030169296546 24.912154735801057 M249.72277866341173 24.848861547932028 C250.40739263938738 59.483614976145326, 249.8095053021796 94.24023997113109, 249.6624052260071 154.96266458891333 M250.1662653012201 25.192355196364225 C250.01118214936926 69.89683146812021, 249.9103734871931 114.68897119965405, 250.17893330883234 155.08975064624101 M250.15045523861684 155.19463287311416 C194.7703673179589 155.33646388878583, 139.31818679162086 155.01027628051926, 49.83021290746828 154.73049000131738 M249.89183244480645 154.93310165197937 C201.6892081104855 155.5109347502242, 153.60549481153024 155.28994757691015, 49.88017214083364 155.1023029807311 M50.028428158536556 155.25564071796833 C50.24258446125314 121.09422902893274, 50.4645724597387 86.7434340238571, 50.355024478212 24.78658777140081 M50.135622064583 154.81267948616295 C49.61699069669471 116.53043805956841, 49.86538132956252 78.29949534665792, 50.18846608232707 24.846260009892283" stroke="#000" stroke-width="4" fill="none"/></g><g><path d="M43.04722050014489 18.258276093946847 C98.72792319271825 18.81226224029811, 153.4515152491855 20.36467495903178, 255.1851150732587 18.45598127014297 M44.19678141163024 19.413435203408945 C125.64690594232708 19.100311479449005, 209.43214010978426 20.324859971231348, 255.36592095706587 18.57053532676623 M254.61389331705868 18.244307739660144 C258.0423227719031 56.304614026658236, 255.05288608586415 94.97427814751863, 254.31202613003552 160.8133229445666 M256.8313265061006 19.96177598182112 C256.07137157080695 67.92298510298133, 255.56732825992628 116.3225115230307, 256.89466654416174 161.44875323120505 M256.7355571239737 161.95153613589483 C197.8962872052512 162.68755860022557, 138.70456541990504 161.09286757305927, 43.16993182411847 159.68239882282856 M255.47118215000765 160.6729422190877 C204.24132620213217 163.60327584438917, 153.5928116551039 162.52289678193645, 43.41417636055329 161.50014666802102 M44.14214079268277 162.27820358984172 C45.30960880378261 124.07270445320755, 46.419548796210435 84.92028873637318, 45.775122391059995 17.932938857004046 M44.67811032291502 160.0633974308148 C41.97672923320904 118.29797793291509, 43.21868239754811 76.78905200343578, 44.94233041163534 18.231300049461424" stroke="rgb(0, 0, 0)" stroke-width="1" fill="none"/></g><text text-anchor="middle" font-family="Consolas, Courier" font-size="22px" fill="rgb(27, 14, 139)" font-weight="bolder" x="150" y="115">"David is cool!"</text><g><path d="M49.78345241285861 24.83142109774053 C65.4576904721558 24.894601719416677, 80.91439656428993 25.247433857955038, 109.81479307152331 24.876355501636862 M50.044724450819196 25.09396549332887 C73.15462117288261 24.880231108143928, 96.79524127598852 25.15854631252587, 109.85588660668581 24.902391331084072 M109.72277866341173 24.848861547932028 C110.40024653943256 38.20590460542589, 109.80235920222476 51.68481922969222, 109.66240522600711 74.96266458891333 M110.16626530122012 25.192355196364225 C109.99056771742181 42.24940276928246, 109.88975905524568 59.39411380197853, 110.17893330883234 75.08975064624101 M110.16717731691897 75.21626499556005 C93.52425968647003 75.26082695763557, 76.8012368466705 74.89838581126183, 49.81134222485125 74.70053579472005 M109.87981035541743 74.92566635478288 C95.39040774870664 75.28829942256212, 81.03313233163207 75.04275102525949, 49.86685408782214 75.11367326248437 M50.028428158536556 75.25564071796835 C50.113669131230566 61.97636435311288, 50.335657129716125 48.50770467221737, 50.355024478212 24.78658777140081 M50.135622064583 74.81267948616296 C49.761289697047324 60.09670382887125, 50.009680329915135 45.432026885263625, 50.18846608232707 24.846260009892283" stroke="#000" stroke-width="4" fill="none"/></g><g><path d="M189.7834524128586 24.83142109774053 C205.4576904721558 24.894601719416677, 220.91439656428992 25.247433857955038, 249.8147930715233 24.876355501636862 M190.0447244508192 25.09396549332887 C213.15462117288263 24.880231108143928, 236.79524127598853 25.15854631252587, 249.85588660668583 24.902391331084072 M249.72277866341173 24.848861547932028 C250.40024653943254 38.20590460542589, 249.80235920222475 51.68481922969222, 249.6624052260071 74.96266458891333 M250.1662653012201 25.192355196364225 C249.9905677174218 42.24940276928246, 249.88975905524566 59.39411380197853, 250.17893330883234 75.08975064624101 M250.16717731691898 75.21626499556005 C233.52425968647003 75.26082695763557, 216.80123684667052 74.89838581126183, 189.81134222485124 74.70053579472005 M249.87981035541742 74.92566635478288 C235.39040774870665 75.28829942256212, 221.0331323316321 75.04275102525949, 189.86685408782213 75.11367326248437 M190.02842815853654 75.25564071796835 C190.11366913123055 61.97636435311288, 190.33565712971614 48.50770467221737, 190.355024478212 24.78658777140081 M190.135622064583 74.81267948616296 C189.76128969704732 60.09670382887125, 190.00968032991514 45.432026885263625, 190.18846608232707 24.846260009892283" stroke="#000" stroke-width="4" fill="none"/></g><text fill="rgb(150, 100, 28)" text-anchor="middle" font-family="Consolas, Courier" font-size="22px" font-weight="bolder" x="80" y="55">id19</text><text fill="rgb(27, 14, 139)" text-anchor="middle" font-family="Consolas, Courier" font-size="22px" font-weight="bolder" x="220" y="55">str</text></svg>"`;
112 changes: 112 additions & 0 deletions memory-viz/src/tests/cli.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const { exec } = require("child_process");
const path = require("path");
const fs = require("fs");
const tmp = require("tmp");

tmp.setGracefulCleanup();

describe("memory-viz cli", () => {
it("should produce an svg that matches snapshot", (done) => {
const tmpFile = tmp.fileSync({ postfix: ".json" });
const filePath = tmpFile.name;
const input = JSON.stringify(
[
{
type: "str",
id: 19,
value: "David is cool!",
style: ["highlight"],
},
],
null
);

fs.writeFileSync(filePath, input);

exec(`memory-viz ${filePath}`, (err) => {
if (err) throw err;
const svgFilePath = path.resolve(
process.cwd(),
path.basename(filePath.replace(".json", ".svg"))
);
const fileContent = fs.readFileSync(svgFilePath, "utf8");
expect(fileContent).toMatchSnapshot();
fs.unlinkSync(svgFilePath);
done();
});
});
});

describe.each([
{
errorType: "invalid arguments",
command: "memory-viz",
expectedErrorMessage:
`Command failed: memory-viz\n` +
`Error: wrong number of arguments.\n` +
`Usage: memory-viz <path-to-file>\n`,
},
{
errorType: "non-existent file",
command: "memory-viz cli-test.json",
expectedErrorMessage:
`Command failed: memory-viz cli-test.json\n` +
`Error: File ${path.resolve(
process.cwd(),
"cli-test.json"
)} does not exist.\n`,
},
{
errorType: "invalid json",
expectedErrorMessage: "Error: Invalid JSON",
},
{
errorType: "invalid memory-viz json",
expectedErrorMessage:
"This is valid JSON but not valid Memory Models JSON." +
"Please refer to the repo for more details.",
},
])(
"these incorrect inputs to the memory-viz cli",
({ errorType, command = undefined, expectedErrorMessage }) => {
it(`should display ${errorType} error`, (done) => {
const fileMockingTests = [
"invalid file type",
"invalid json",
"invalid memory-viz json",
];

let filePath: string;
if (fileMockingTests.includes(errorType)) {
let err_postfix: string;
if (errorType === "invalid file type") {
err_postfix = ".js";
} else {
err_postfix = ".json";
}
const tmpFile = tmp.fileSync({ postfix: err_postfix });
filePath = tmpFile.name;

if (errorType === "invalid json") {
fs.writeFileSync(filePath, "[1, 2, 3, 4,]");
} else {
fs.writeFileSync(
filePath,
'[{ "name": "int", "id": 13, "value": 7 }]'
);
}
}

if (fileMockingTests.includes(errorType)) {
command = `memory-viz ${filePath}`;
}
exec(command, (err) => {
if (err) {
expect(err.code).toBe(1);
expect(err.message).toContain(expectedErrorMessage);
}
done();
});
});
}
);
15 changes: 14 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"devDependencies": {
"husky": "^8.0.3",
"lint-staged": "^14.0.1",
"prettier": "2.8.1"
"prettier": "2.8.1",
"tmp": "^0.2.3"
},
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
Expand Down

0 comments on commit da9c3d5

Please sign in to comment.