{"_id":"gently","_rev":"77976","name":"gently","description":"<!-- badges/ --> [![Build Status](https://travis-ci.org/felixge/node-gently.svg?branch=master)](https://travis-ci.org/felixge/node-gently) [![npm](https://img.shields.io/npm/v/gently.svg)](https://www.npmjs.com/package/gently)  [![Dependency Status](https","dist-tags":{"latest":"1.0.0"},"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"time":{"modified":"2021-06-03T10:25:02.000Z","created":"2011-05-03T16:45:23.222Z","1.0.0":"2021-05-21T08:45:03.302Z","0.10.0":"2015-08-03T14:55:56.164Z","0.9.2":"2012-06-03T20:23:12.934Z","0.9.1":"2011-05-24T13:40:08.508Z","0.6.0":"2011-05-03T16:45:23.222Z","0.1.0":"2011-05-03T16:45:23.222Z","0.3.0":"2011-05-03T16:45:23.222Z","0.4.0":"2011-05-03T16:45:23.222Z","0.5.0":"2011-05-03T16:45:23.222Z","0.2.0":"2011-05-03T16:45:23.222Z","0.7.0":"2011-05-03T16:45:23.222Z","0.8.0":"2011-05-03T16:45:23.222Z","0.9.0":"2011-05-03T16:45:23.222Z"},"users":{"tunnckocore":true},"repository":{"type":"git","url":"git+https://github.com/felixge/node-gently.git"},"versions":{"1.0.0":{"name":"gently","version":"1.0.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","repository":{"type":"git","url":"git+https://github.com/felixge/node-gently.git"},"dependencies":{},"devDependencies":{},"engines":{"node":"*"},"optionalDependencies":{},"gitHead":"b54d98695ace53baa5507bcf8afa18a5d6b0e110","description":"<!-- badges/ --> [![Build Status](https://travis-ci.org/felixge/node-gently.svg?branch=master)](https://travis-ci.org/felixge/node-gently) [![npm](https://img.shields.io/npm/v/gently.svg)](https://www.npmjs.com/package/gently)  [![Dependency Status](https","bugs":{"url":"https://github.com/felixge/node-gently/issues"},"homepage":"https://github.com/felixge/node-gently#readme","_id":"gently@1.0.0","_nodeVersion":"15.9.0","_npmVersion":"7.7.6","dist":{"shasum":"ea6a53700e055b2d8ae7748e24df3a96c4dc5b18","size":5994,"noattachment":false,"key":"/gently/-/gently-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-1.0.0.tgz"},"_npmUser":{"name":"juliangruber","email":"julian@juliangruber.com"},"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/gently_1.0.0_1621586703137_0.12008859294651919"},"_hasShrinkwrap":false,"publish_time":1621586703302,"_cnpm_publish_time":1621586703302},"0.10.0":{"name":"gently","version":"0.10.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","repository":{"type":"git","url":"git+https://github.com/felixge/node-gently.git"},"dependencies":{},"devDependencies":{},"engines":{"node":"*"},"optionalDependencies":{},"gitHead":"fa9774cff356aa0fd30dda69f64031a9993e638a","description":"<!-- badges/ --> [![Build Status](https://travis-ci.org/felixge/node-gently.svg?branch=master)](https://travis-ci.org/felixge/node-gently) [![npm](https://img.shields.io/npm/v/gently.svg)](https://www.npmjs.com/package/gently)  [![Dependency Status](https","bugs":{"url":"https://github.com/felixge/node-gently/issues"},"homepage":"https://github.com/felixge/node-gently#readme","_id":"gently@0.10.0","scripts":{},"_shasum":"de4b3f0bb8b853be4b9fc2edd17f2d3c2e33bc28","_from":".","_npmVersion":"2.10.1","_nodeVersion":"0.12.4","_npmUser":{"name":"kvz","email":"kevin@vanzonneveld.net"},"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"dist":{"shasum":"de4b3f0bb8b853be4b9fc2edd17f2d3c2e33bc28","size":6009,"noattachment":false,"key":"/gently/-/gently-0.10.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.10.0.tgz"},"publish_time":1438613756164,"_cnpm_publish_time":1438613756164,"_hasShrinkwrap":false},"0.9.2":{"name":"gently","version":"0.9.2","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"optionalDependencies":{},"_npmUser":{"name":"felixge","email":"felix@debuggable.com"},"_id":"gently@0.9.2","_engineSupported":true,"_npmVersion":"1.1.19","_nodeVersion":"v0.6.16","_defaultsLoaded":true,"dist":{"shasum":"37aa072ba0894274cde5287e13eee8a1ffc2fb58","size":5533,"noattachment":false,"key":"/gently/-/gently-0.9.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.9.2.tgz"},"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"publish_time":1338754992934,"_hasShrinkwrap":false,"_cnpm_publish_time":1338754992934},"0.9.1":{"name":"gently","version":"0.9.1","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_id":"gently@0.9.1","_engineSupported":true,"_npmVersion":"1.0.3","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"280c3b4004305d42830dd49e07af3502c45e4a0b","size":5337,"noattachment":false,"key":"/gently/-/gently-0.9.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.9.1.tgz"},"scripts":{},"publish_time":1306244408508,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1306244408508},"0.6.0":{"name":"gently","version":"0.6.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.6.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"216748285f87a6d52e31c71a7e74851313b401d5","size":4516,"noattachment":false,"key":"/gently/-/gently-0.6.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.6.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.1.0":{"name":"gently","version":"0.1.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.1.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"5ad83327c7f4ec18b1ac01f57f4b806c66a2bf66","size":3436,"noattachment":false,"key":"/gently/-/gently-0.1.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.1.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.3.0":{"name":"gently","version":"0.3.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.3.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"c8f26e8483b66db78ec8d08929d4ce8f260cc630","size":3524,"noattachment":false,"key":"/gently/-/gently-0.3.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.3.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.4.0":{"name":"gently","version":"0.4.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.4.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"d61878a4a24b75e39a3ed2d403c86af0b93fa616","size":4137,"noattachment":false,"key":"/gently/-/gently-0.4.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.4.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.5.0":{"name":"gently","version":"0.5.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.5.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"90a7f88cdf34d7c8057dcf7208776672d9d53f2c","size":4301,"noattachment":false,"key":"/gently/-/gently-0.5.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.5.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.2.0":{"name":"gently","version":"0.2.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.2.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"702aae4ce8ce68f57c1810daccdf4a2c7071d29e","size":3501,"noattachment":false,"key":"/gently/-/gently-0.2.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.2.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.7.0":{"name":"gently","version":"0.7.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.7.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"48f06a53071d782ced6e19648f765bf9b036e0fe","size":6090,"noattachment":false,"key":"/gently/-/gently-0.7.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.7.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.8.0":{"name":"gently","version":"0.8.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","_id":"gently@0.8.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"shasum":"bc385db99ec1994dd6a44368e0abeb482b192b2c","size":7138,"noattachment":false,"key":"/gently/-/gently-0.8.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.8.0.tgz"},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222},"0.9.0":{"name":"gently","version":"0.9.0","directories":{"lib":"./lib/gently"},"main":"./lib/gently/index","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"_id":"gently@0.9.0","_engineSupported":true,"_npmVersion":"1.0.3","_nodeVersion":"v0.4.8-pre","_defaultsLoaded":true,"dist":{"shasum":"f6d73a8cf774917fd419e0df276edb4c272719d2","size":5248,"noattachment":false,"key":"/gently/-/gently-0.9.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/gently/download/gently-0.9.0.tgz"},"scripts":{},"publish_time":1304441123222,"maintainers":[{"name":"felixge","email":"felix@debuggable.com"},{"name":"juliangruber","email":"julian@juliangruber.com"},{"name":"kvz","email":"kevin@vanzonneveld.net"}],"_hasShrinkwrap":false,"_cnpm_publish_time":1304441123222}},"readme":"# Gently\n\n<!-- badges/ -->\n[![Build Status](https://travis-ci.org/felixge/node-gently.svg?branch=master)](https://travis-ci.org/felixge/node-gently)\n[![npm](https://img.shields.io/npm/v/gently.svg)](https://www.npmjs.com/package/gently) \n[![Dependency Status](https://david-dm.org/felixge/node-gently.svg?theme=shields.io)](https://david-dm.org/felixge/node-gently)\n[![Development Dependency Status](https://david-dm.org/felixge/node-gently/dev-status.svg?theme=shields.io)](https://david-dm.org/felixge/node-gently#info=devDependencies)\n<!-- /badges -->\n\n## Purpose\n\nA node.js module that helps with stubbing and behavior verification. It allows you to test the most remote and nested corners of your code while keeping being fully unobtrusive.\n\n## Features\n\n* Overwrite and stub individual object functions\n* Verify that all expected calls have been made in the expected order\n* Restore stubbed functions to their original behavior\n* Detect object / class names from obj.constructor.name and obj.toString()\n* Hijack any required module function or class constructor\n\n## Installation\n\nVia [npm](http://github.com/isaacs/npm):\n\n    npm install gently@latest\n\n## Example\n\nMake sure your dog is working properly:\n```javascript\nfunction Dog() {}\n\nDog.prototype.seeCat = function() {\n  this.bark('whuf, whuf');\n  this.run();\n}\n\nDog.prototype.bark = function(bark) {\n  require('sys').puts(bark);\n}\n\nconst gently = new (require('gently'))\n  , assert = require('assert')\n  , dog = new Dog();\n\ngently.expect(dog, 'bark', function(bark) {\n  assert.equal(bark, 'whuf, whuf');\n});\ngently.expect(dog, 'run');\n\ndog.seeCat();\n```\nYou can also easily test event emitters with this, for example a simple sequence of 2 events emitted by `fs.WriteStream`:\n```javascript\nconst gently = new (require('gently'))\n  , stream = new (require('fs').WriteStream)('my_file.txt');\n\ngently.expect(stream, 'emit', function(event) {\n  assert.equal(event, 'open');\n});\n\ngently.expect(stream, 'emit', function(event) {\n  assert.equal(event, 'drain');\n});\n```\nFor a full read world example, check out this test case: [test-incoming-form.js](http://github.com/felixge/node-formidable/blob/master/test/simple/test-incoming-form.js) (in [node-formdiable](http://github.com/felixge/node-formidable)).\n\n## API\n\n### Gently\n\n#### new Gently()\n\nCreates a new gently instance. It listens to the process `'exit'` event to make sure all expectations have been verified.\n\n#### gently.expect(obj, method, [[count], stubFn])\n\nCreates an expectation for an objects method to be called. You can optionally specify the call `count` you are expecting, as well as `stubFn` function that will run instead of the original function.\n\nReturns a reference to the function that is getting overwritten.\n\n#### gently.expect([count], stubFn)\n\nReturns a function that is supposed to be executed `count` times, delegating any calls to the provided `stubFn` function. Naming your stubFn closure will help to properly diagnose errors that are being thrown:\n```javascript\nchildProcess.exec('ls', gently.expect(function lsCallback(code) {\n  assert.equal(0, code);\n}));\n```\n#### gently.restore(obj, method)\n\nRestores an object method that has been previously overwritten using `gently.expect()`.\n\n#### gently.hijack(realRequire)\n\nReturns a new require functions that catches a reference to all required modules into `gently.hijacked`.\n\nTo use this function, include a line like this in your `'my-module.js'`.\n```javascript\nif (global.GENTLY) require = GENTLY.hijack(require);\n\nconst sys = require('sys');\nexports.hello = function() {\n  sys.log('world');\n};\n```\nNow you can write a test for the module above:\n```javascript\nconst gently = global.GENTLY = new (require('gently'))\n  , myModule = require('./my-module');\n\ngently.expect(gently.hijacked.sys, 'log', function(str) {\n  assert.equal(str, 'world');\n});\n\nmyModule.hello();\n```\n#### gently.stub(location, [exportsName])\n\nReturns a stub class that will be used instead of the real class from the module at `location` with the given `exportsName`.\n\nThis allows to test an OOP version of the previous example, where `'my-module.js'`.\n```javascript\nif (global.GENTLY) require = GENTLY.hijack(require);\n\nconst World = require('./world');\n\nexports.hello = function() {\n  const world = new World();\n  world.hello();\n}\n```\nAnd `world.js` looks like this:\n```javascript\nconst sys = require('sys');\n\nfunction World() {\n\n}\nmodule.exports = World;\n\nWorld.prototype.hello = function() {\n  sys.log('world');\n};\n```\nTesting `'my-module.js'` can now easily be accomplished:\n```javascript\nconst gently = global.GENTLY = new (require('gently'))\n  , WorldStub = gently.stub('./world')\n  , myModule = require('./my-module')\n  , WORLD;\n\ngently.expect(WorldStub, 'new', function() {\n  WORLD = this;\n});\n\ngently.expect(WORLD, 'hello');\n\nmyModule.hello();\n```\n#### gently.hijacked\n\nAn object that holds the references to all hijacked modules.\n\n#### gently.verify([msg])\n\nVerifies that all expectations of this gently instance have been satisfied. If not called manually, this method is called when the process `'exit'` event is fired.\n\nIf `msg` is given, it will appear in any error that might be thrown.\n\n## License\n\nGently is licensed under the MIT license.\n","_attachments":{},"homepage":"https://github.com/felixge/node-gently#readme","bugs":{"url":"https://github.com/felixge/node-gently/issues"}}