apache / couchdb

Seamless multi-master syncing database with an intuitive HTTP/JSON API, designed for reliability
https://couchdb.apache.org/
Apache License 2.0
6.25k stars 1.03k forks source link

Enable unit-testing of designdoc functions using CommonJS #2763

Open cefn opened 4 years ago

cefn commented 4 years ago

The documented Couchdb support for CommonJS makes it difficult to author functions for map, reduce, update etc. which use shared code and which can both be

This can be addressed with a minor improvement to require() behaviour, or by documenting support if there is in fact some way to do this.

Summary

I have succeeded at putting together unit testing of a map function in NodeJS, followed by component testing of the resulting view in Couchdb.

However, I face the restriction that all functions have to be monolithic (not use require), since I can't get any script using require to work both locally in the filesystem for unit testing and remotely in couchdb for component testing because of restrictions on require() paths. This makes it hard to maintain the codebase of my view functions.

Possible Solutions

This issue could be addressed by a change to the CommonJS require() feature to add relative paths, or potentially by improved documentation.

Solution: Documenting How

If there is already some way to achieve scripts which can have requires which are consistent for both local and remote imports, this could be documented to assist in test-driven development of Spidermonkey functions.

Solution: Making require() resolve relative paths

Allowing relatively-addressed CommonJS require() paths (instead of requires all being rooted in the global namespace at "view/lib" ) would make it straightforward to define locally-run scripts-and-requires which directly mirror the server-side scripts-and-requires, simply by placing the source files in a directory hierarchy which mirrors the designdoc JSON tree hierarchy.

The Couchdb CommonJS documentation states all requireable modules must be addressed as modules in the globally-rooted namespace with a "view/lib" prefix like require("view/lib/mymodule"). This prevents the use of modules with relative paths such as require("../lib/mymodule") from within a view map function.

With support for relative paths, locally-developed scripts would be able to evaluate properly in Node for unit-testing.

Additional Context

For reference, I am including gists with testing code from a private repo.

wohali commented 4 years ago

Would ln -s .. view work ?

cefn commented 4 years ago

It's a solid idea. When I'm back on it, I'll restructure my source and try to set up a softlink at {project_root}/node_modules/view/lib pointing to e.g. {project_root}/couchdb/designdocs/{viewname}/lib

It has the shortcoming that the softlink would only work in suitable filesystems, and would have to be dynamically switched by the testing environment depending on the {viewname} under test but if the hack works, it's certainly an option. Only has to work in the testing environment after all.