diff --git a/node/README.md b/node/README.md index 1a1220b981..f1d61c7970 100644 --- a/node/README.md +++ b/node/README.md @@ -36,6 +36,10 @@ Please run formatting, linting and testing before contributing code e.g. make format lint test ``` +### Testing + +There are tests in `src/*.test.ts` files. Note that most of these tests are aimed at picking up regressions in the API of this package, and not of the correctness of the wrapped Rust code for which tests exists in `../rust`. + ### Project Layout This project was bootstrapped by [create-neon](https://www.npmjs.com/package/create-neon). Its directory structure is something like: diff --git a/node/src/documents.rs b/node/src/documents.rs index 7cf25f12cf..26b1aaff65 100644 --- a/node/src/documents.rs +++ b/node/src/documents.rs @@ -88,6 +88,23 @@ pub fn write(mut cx: FunctionContext) -> JsResult { to_undefined_or_throw(cx, result) } +/// Write a document to another path / format +pub fn write_as(mut cx: FunctionContext) -> JsResult { + let id = &cx.argument::(0)?.value(&mut cx); + let path = cx.argument::(1)?.value(&mut cx); + let format = cx.argument::(2)?.value(&mut cx); + let format = if format.is_empty() { + None + } else { + Some(format) + }; + let theme = cx.argument::(3)?.value(&mut cx); + let theme = if theme.is_empty() { None } else { Some(theme) }; + let documents = &mut *obtain(&mut cx)?; + let result = RUNTIME.block_on(async { documents.write_as(id, &path, format, theme).await }); + to_undefined_or_throw(cx, result) +} + /// Dump a document pub fn dump(mut cx: FunctionContext) -> JsResult { let id = &cx.argument::(0)?.value(&mut cx); diff --git a/node/src/documents.test.ts b/node/src/documents.test.ts index e1a25fc683..264a4d226b 100644 --- a/node/src/documents.test.ts +++ b/node/src/documents.test.ts @@ -9,6 +9,7 @@ import { subscribe, unsubscribe, write, + writeAs, } from './documents' import { DocumentEvent } from './types' @@ -32,6 +33,28 @@ test('create', async () => { ) }) +/** + * Test of a workflow involving creating a new document and then + * saving it as other files in same and other formats. + */ +test('workfow-create-write-as', async () => { + const doc = create('json'); + expect(doc).toEqual( + expect.objectContaining({ + temporary: true, + name: 'Unnamed', + }) + ) + + const path1 = tmp.fileSync({ postfix: '.json' }).name + writeAs(doc.id, path1) + fs.existsSync(path1) + + const path2 = tmp.fileSync({ postfix: '.markdown' }).name + writeAs(doc.id, path2, "md") + fs.existsSync(path2) +}) + /** * Test of a workflow involving opening and modifying a document * @@ -166,3 +189,4 @@ test('workflow-open-modify', async () => { fs.unlinkSync(path) }) + diff --git a/node/src/documents.ts b/node/src/documents.ts index f1cf991d91..4c8e6b617f 100644 --- a/node/src/documents.ts +++ b/node/src/documents.ts @@ -74,6 +74,23 @@ export function write(id: string, content: string): string { return addon.documentsWrite(id, content) } +/** + * Write the content of a document to the file system. + * + * @param id Id of the document + * @param path Path of the new document + * @param format Format of the new document (inferred from path if not supplied) + * @param theme Theme for the new document (only applies to some formats e.g. HTML, PDF) + */ +export function writeAs( + id: string, + path: string, + format: string = '', + theme: string = '' +): string { + return addon.documentsWriteAs(id, path, format, theme) +} + /** * Dump the current content of a document without reading it * from the file system. The inverse of `load()`. @@ -134,7 +151,7 @@ export function unsubscribe(id: string, topics: string[]): void { /** * Close a document. - * + * * This will drop the document from memory and stop any * associated file watching thread. * diff --git a/node/src/lib.rs b/node/src/lib.rs index 5d0c68b484..6d36a32e6f 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -22,6 +22,7 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> { cx.export_function("documentsGet", documents::get)?; cx.export_function("documentsRead", documents::read)?; cx.export_function("documentsWrite", documents::write)?; + cx.export_function("documentsWriteAs", documents::write_as)?; cx.export_function("documentsDump", documents::dump)?; cx.export_function("documentsLoad", documents::load)?; cx.export_function("documentsSubscribe", documents::subscribe)?; diff --git a/rust/src/documents.rs b/rust/src/documents.rs index 79ccbd84a6..b4ecd324f0 100644 --- a/rust/src/documents.rs +++ b/rust/src/documents.rs @@ -911,6 +911,20 @@ impl Documents { self.get(&id)?.lock().await.write(content, None).await } + pub async fn write_as( + &mut self, + id: &str, + path: &str, + format: Option, + theme: Option, + ) -> Result<()> { + self.get(&id)? + .lock() + .await + .write_as(path, format, theme) + .await + } + pub async fn dump(&mut self, id: &str, format: Option) -> Result { self.get(&id)?.lock().await.dump(format).await }