From 701a7fcba8e13b36a5b4a0eae25e865ac98c017e Mon Sep 17 00:00:00 2001 From: Sarah Wang <55766946+sarahsonder@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:45:45 -0400 Subject: [PATCH] Add --roughjs_config option for MemoryViz CLI (#48) --- CHANGELOG.md | 1 + docs/docs/06-cli.md | 32 +++++- memory-viz/bin/cli.js | 24 +++-- .../src/tests/__snapshots__/cli.spec.tsx.snap | 2 + memory-viz/src/tests/cli.spec.tsx | 100 +++++++++++------- 5 files changed, 112 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0efe3b7..45149534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Created a CLI for MemoryViz. - Added `--height` and `--width` options to MemoryViz CLI. +- Added `--roughjs_config` option to MemoryViz CLI. ### 🐛 Bug fixes diff --git a/docs/docs/06-cli.md b/docs/docs/06-cli.md index 1d7f5e37..ef2aa46c 100644 --- a/docs/docs/06-cli.md +++ b/docs/docs/06-cli.md @@ -16,8 +16,36 @@ $ npx memory-viz replacing `` with the path to a file containing MemoryViz-compatible JSON. If the file content is not compatible with MemoryViz, an error will be thrown. -Optional arguments `--height` and `--width` can be used to specify the height and width of the generated SVG. - ## 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`). + +## Options + +Below are optional arguments used to specify the way in which the SVG image is generated. + +### `--width` + +Specifies the width of the generated SVG. + +```console +$ npx memory-viz --width=700 +``` + +### `--height` + +Specifies the height of the generated SVG. + +```console +$ npx memory-viz --height=700 +``` + +### `--roughjs_config` + +Specifies the style of the generated SVG. Please refer to the [Rough.js documentation](https://github.com/rough-stuff/rough/wiki#options) for available options. + +The argument is a comma-separated list of key-value pairs in the form ``. + +```console +$ npx memory-viz --roughjs-config fill=red,fillStyle=solid +``` diff --git a/memory-viz/bin/cli.js b/memory-viz/bin/cli.js index 47b2a6a4..4ed24f36 100644 --- a/memory-viz/bin/cli.js +++ b/memory-viz/bin/cli.js @@ -5,6 +5,12 @@ const path = require("path"); const { draw } = require("memory-viz"); const { program } = require("commander"); +function parseRoughjsConfig(input) { + const pairs = input.split(","); + const keyValuePairs = pairs.map((pair) => pair.split("=")); + return Object.fromEntries(keyValuePairs); +} + program .description( "Command line interface for generating memory model diagrams with MemoryViz" @@ -14,14 +20,20 @@ program "path to a file containing MemoryViz-compatible JSON" ) .option("--width ", "width of generated SVG", "1300") - .option("--height ", "height of generated SVG"); + .option("--height ", "height of generated SVG") + .option( + "--roughjs-config ", + "options to configure how the SVG is drawn" + + " - refer to rough.js documentation for available options", + parseRoughjsConfig + ); program.parse(); const filePath = program.args[0]; const absolutePath = path.resolve(process.cwd(), filePath); -// Checks if absolutePath exists and that it is a JSON file +// Checks if absolutePath exists let fileContent; if (!fs.existsSync(absolutePath)) { console.error(`Error: File ${absolutePath} does not exist.`); @@ -40,17 +52,13 @@ try { let m; try { - // TODO: Replace seed with command-line arguments m = draw(data, true, { width: program.opts().width, height: program.opts().height, - roughjs_config: { options: { seed: 12345 } }, + roughjs_config: { options: program.opts().roughjsConfig }, }); } catch (err) { - console.error( - `This is valid JSON but not valid Memory Models JSON.` + - `Please refer to the repo for more details.` - ); + console.error(`Error: ${err.message}`); process.exit(1); } diff --git a/memory-viz/src/tests/__snapshots__/cli.spec.tsx.snap b/memory-viz/src/tests/__snapshots__/cli.spec.tsx.snap index 3c1851f7..8d162274 100644 --- a/memory-viz/src/tests/__snapshots__/cli.spec.tsx.snap +++ b/memory-viz/src/tests/__snapshots__/cli.spec.tsx.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`memory-viz cli produces consistent svg when provided a variety of rough-config options 1`] = `""David is cool!"id19str"`; + exports[`memory-viz cli produces consistent svg when provided height and width options 1`] = `""David is cool!"id19str"`; exports[`memory-viz cli produces consistent svg when provided height option 1`] = `""David is cool!"id19str"`; diff --git a/memory-viz/src/tests/cli.spec.tsx b/memory-viz/src/tests/cli.spec.tsx index eea7f45a..b6e3e5ff 100644 --- a/memory-viz/src/tests/cli.spec.tsx +++ b/memory-viz/src/tests/cli.spec.tsx @@ -23,7 +23,7 @@ describe("memory-viz cli", () => { it("should produce an svg that matches snapshot", (done) => { fs.writeFileSync(filePath, input); - exec(`memory-viz ${filePath}`, (err) => { + exec(`memory-viz ${filePath} --roughjs-config seed=12345`, (err) => { if (err) throw err; const svgFilePath = path.resolve( process.cwd(), @@ -39,49 +39,77 @@ describe("memory-viz cli", () => { it("produces consistent svg when provided width option", (done) => { fs.writeFileSync(filePath, input); - exec(`memory-viz ${filePath} --width=700`, (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(); - }); + exec( + `memory-viz ${filePath} --width=700 --roughjs-config seed=12345`, + (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(); + } + ); }); it("produces consistent svg when provided height option", (done) => { fs.writeFileSync(filePath, input); - exec(`memory-viz ${filePath} --height=700`, (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(); - }); + exec( + `memory-viz ${filePath} --height=700 --roughjs-config seed=12345`, + (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(); + } + ); }); it("produces consistent svg when provided height and width options", (done) => { fs.writeFileSync(filePath, input); - exec(`memory-viz ${filePath} --height=700 width=1200`, (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(); - }); + exec( + `memory-viz ${filePath} --height=700 width=1200 --roughjs-config seed=12345`, + (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(); + } + ); + }); + + it("produces consistent svg when provided a variety of rough-config options", (done) => { + fs.writeFileSync(filePath, input); + + exec( + `memory-viz ${filePath} --roughjs-config seed=1234,fill=red,fillStyle=solid`, + (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(); + } + ); }); }); @@ -107,9 +135,7 @@ describe.each([ }, { errorType: "invalid memory-viz json", - expectedErrorMessage: - "This is valid JSON but not valid Memory Models JSON." + - "Please refer to the repo for more details.", + expectedErrorMessage: "Error:", }, ])( "these incorrect inputs to the memory-viz cli",