UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

191 lines (129 loc) 5.37 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Class('Scope.Provider.NodeJS', { isa : Scope.Provider, has : { sourceURL : null, requireFunc : null, errorHandlerBorrowed : null, onErrorHandler : null }, methods : { runInContext : function (code, scope, options) { var vm = require('vm') return vm.runInContext(code, scope, options) }, addOnErrorHandler : function (handler, preventDefault) { var me = this if (me.eventHandlerBorrowed) throw new Error("Exclusive resource borrowing failed") me.onErrorHandler = handler var exceptionHander var rejectionHandler process.on('uncaughtException', exceptionHandler = function (e) { handler(e.message, null, null, null, e) }) process.on('unhandledRejection', rejectHandler = function (reason) { handler(null, null, null, null, null, { reason : reason }) }) return me.eventHandlerBorrowed = function () { process.removeListener('uncaughtException', exceptionHandler) process.removeListener('unhandledRejection', rejectHandler) me.eventHandlerBorrowed = null me.onErrorHandler = null } }, create : function (callback) { var vm = require('vm') var sandbox = {} Joose.O.extend(sandbox, { process : process, console : console, global : sandbox, // TODO wrap this in functions in target context // currently in the test context `setTimeout instanceOf Function === false` setImmediate : setImmediate, clearImmediate : clearImmediate, setTimeout : setTimeout, clearTimeout : clearTimeout, setInterval : setInterval, clearInterval : clearInterval }) var scope = this.scope = vm.createContext(sandbox) callback && callback() }, setup : function (callback) { this.create() var me = this if (this.seedingCode) this.runCode(this.seedingCode) Joose.A.each(this.getPreload(), function (preloadDesc) { if (preloadDesc.type == 'js') if (preloadDesc.url) me.runScript(preloadDesc.url) else me.runCode(preloadDesc.content) }) if (this.seedingScript) { this.runScript(this.seedingScript) } callback && callback(me) }, stripBom : function (content) { // Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) // because the buffer-to-string conversion in `fs.readFileSync()` // translates it to FEFF, the UTF-16 BOM. if (content.charCodeAt(0) === 0xFEFF) content = content.slice(1) return content }, fileNameToModuleId : function (url) { var path = require('path') var filename if (path.isAbsolute(url)) { filename = url } else { filename = path.resolve('./', url) } return filename }, runCode : function (text, callback) { var vm = require('vm') var res = vm.runInContext(this.stripBom(text), this.scope) callback && callback(res) return res }, runScript : function (url, callback) { if (/mjs(\?.*)?$/.test(url)) { return this.importEcmaModule(url, callback) } else return this.requireCjsModule(url, callback) }, requireCjsModule : function (url, callback) { var vm = require('vm') var old = vm.runInThisContext var scope = this.scope vm.runInThisContext = function (code, options) { return vm.runInContext(code, scope, options) } try { var res = this.requireFunc(this.fileNameToModuleId(url)) } catch (e) { this.onErrorHandler && this.onErrorHandler(e.message, null, null, null, e) } vm.runInThisContext = old callback && callback(res) return res }, importEcmaModule : function (url, callback) { // seems node only support dynamic `import` for the current context // see how it is implemented in NodeJsEmbed throw new Error("Ecma module for different context - implement me?") }, cleanup : function () { if (this.beforeCleanupCallback) this.beforeCleanupCallback() if (this.cleanupCallback) this.cleanupCallback() } } })