UNPKG

siesta-lite

Version:

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

315 lines (227 loc) 10.6 kB
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js">/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ <span id='Siesta-Test-BDD-Spy'>/** </span>@class Siesta.Test.BDD.Spy This class implements a &quot;spy&quot; - function wrapper which tracks the calls to itself. Spy can be installed instead of a method in some object or can be used standalone. Note, that spies &quot;belongs&quot; to a spec and once the spec is completed all spies that were installed during it will be removed. */ Class(&#39;Siesta.Test.BDD.Spy&#39;, { does : [ Siesta.Util.Role.CanGetType ], has : { name : null, processor : { lazy : &#39;this.buildProcessor&#39; }, hostObject : null, propertyName : null, hasOwnOriginalValue : false, originalValue : null, strategy : &#39;callThrough&#39;, returnValueObj : undefined, fakeFunc : null, throwErrorObj : null, // array of { object : scope, args : [], returnValue : } callsLog : Joose.I.Array, <span id='Siesta-Test-BDD-Spy-property-calls'> /** </span> * @property {Object} calls This is an object property with several helper methods, related to the calls * tracking information. It is assigned to the wrapper function of spy. * * @property {Function} calls.any Returns `true` if spy was called at least once, `false` otherwise * @property {Function} calls.count Returns the number of times this spy was called * @property {Function} calls.argsFor Accepts an number of the call (0-based) and return an array of arguments * for that call. * @property {Function} calls.allArgs Returns an array with the arguments for every tracked function call. * Every element of the array is, in turn, an array of arguments. * @property {Function} calls.all Returns an array with the context for every tracked function call. * Every element of the array is an object of the following structure: { object : this, args : [ 0, 1, 2 ], returnValue : undefined } * @property {Function} calls.mostRecent Returns a context object of the most-recent tracked function call. * @property {Function} calls.first Returns a context object of the first tracked function call. * @property {Function} calls.reset Reset all tracking data. * * * Example: t.spyOn(obj, &#39;someMethod&#39;).callThrough() obj.someMethod(0, 1) obj.someMethod(1, 2) t.expect(obj.someMethod.calls.any()).toBe(true) t.expect(obj.someMethod.calls.count()).toBe(2) t.expect(obj.someMethod.calls.first()).toEqual({ object : obj, args : [ 0, 1 ], returnValue : undefined }) */ calls : null, t : null, <span id='Siesta-Test-BDD-Spy-property-and'> /** </span> * @property {Siesta.Test.BDD.Spy} and This is just a reference to itself, to add some syntax sugar. * * This property is also assigned to the wrapper function of spy. * t.spyOn(obj, &#39;someMethod&#39;).callThrough() // same thing as above t.spyOn(obj, &#39;someMethod&#39;).and.callThrough() // returns spy instance obj.someMethod.and */ and : function () { return this } }, methods : { initialize : function () { var me = this this.calls = { any : function () { return me.callsLog.length &gt; 0 }, count : function () { return me.callsLog.length }, argsFor : function (i) { return me.callsLog[ i ].args }, allArgs : function (i) { return Joose.A.map(me.callsLog, function (call) { return call.args } ) }, all : function () { return me.callsLog }, mostRecent : function () { return me.callsLog[ me.callsLog.length - 1 ] }, first : function () { return me.callsLog[ 0 ] }, reset : function () { me.reset() } } var R = Siesta.Resource(&#39;Siesta.Test.BDD.Spy&#39;) var hostObject = this.hostObject var propertyName = this.propertyName if (hostObject) { var originalValue = hostObject[ propertyName ] if (!/Function/.test(this.typeOf(originalValue))) throw R.get(&quot;spyingNotOnFunction&quot;) if (originalValue.__SIESTA_SPY__) originalValue.__SIESTA_SPY__.remove() this.originalValue = hostObject[ propertyName ] this.hasOwnOriginalValue = hostObject.hasOwnProperty(propertyName) hostObject[ propertyName ] = this.getProcessor() } if (this.t) this.t.spies.push(this) }, buildProcessor : function () { var me = this var processor = function () { var args = Array.prototype.slice.call(arguments) var log = { object : this, args : args } me.callsLog.push(log) return log.returnValue = me[ me.strategy + &#39;Strategy&#39; ](this, args) } processor.__SIESTA_SPY__ = processor.and = me processor.calls = me.calls return processor }, returnValueStrategy : function (obj, args) { return this.returnValueObj }, callThroughStrategy : function (obj, args) { return this.originalValue.apply(obj, args) }, callFakeStrategy : function (obj, args) { return this.fakeFunc.apply(obj, args) }, throwErrorStrategy : function (obj, args) { var error = this.throwErrorObj var ERROR = this.t &amp;&amp; this.t.global ? this.t.global.Error : Error if (!(error instanceof ERROR)) error = new ERROR(error) throw error }, <span id='Siesta-Test-BDD-Spy-method-callThrough'> /** </span> * This method makes the spy to also execute the original function it has been installed over. The * value returned from original function is returned from the spy. * * @return {Siesta.Test.BDD.Spy} This spy instance */ callThrough : function () { if (!this.hostObject) throw &quot;Need the host object to call through to original method&quot; this.strategy = &#39;callThrough&#39; return this }, <span id='Siesta-Test-BDD-Spy-method-stub'> /** </span> * This method makes the spy to just return `undefined` and not execute the original function. * * @return {Siesta.Test.BDD.Spy} This spy instance */ stub : function () { this.returnValue() return this }, <span id='Siesta-Test-BDD-Spy-method-returnValue'> /** </span> * This method makes the spy to return the value provided and not execute the original function. * * @param {Object} value The value that will be returned from the spy. * * @return {Siesta.Test.BDD.Spy} This spy instance */ returnValue : function (value) { this.strategy = &#39;returnValue&#39; this.returnValueObj = value return this }, <span id='Siesta-Test-BDD-Spy-method-callFake'> /** </span> * This method makes the spy to call the provided function and return the value from it, instead of the original function. * * @param {Function} func The function to call instead of the original function * * @return {Siesta.Test.BDD.Spy} This spy instance */ callFake : function (func) { this.strategy = &#39;callFake&#39; this.fakeFunc = func return this }, <span id='Siesta-Test-BDD-Spy-method-throwError'> /** </span> * This method makes the spy to throw the specified `error` value (instead of calling the original function). * * @param {Object} error The error value to throw. If it is not an `Error` instance, it will be passed to `Error` constructor first. * * @return {Siesta.Test.BDD.Spy} This spy instance */ throwError : function (error) { this.strategy = &#39;throwError&#39; this.throwErrorObj = error return this }, remove : function () { var hostObject = this.hostObject if (hostObject) { if (this.hasOwnOriginalValue) hostObject[ this.propertyName ] = this.originalValue else delete hostObject[ this.propertyName ] } // cleanup paranoya this.originalValue = this.hostObject = hostObject = null this.callsLog = [] this.returnValueObj = this.fakeFunc = this.throwErrorObj = null var processor = this.getProcessor() if (processor) processor.and = processor.calls = processor.__SIESTA_SPY__ = null this.processor = null }, <span id='Siesta-Test-BDD-Spy-method-reset'> /** </span> * This method resets all calls tracking data. Spy will report as it has never been called yet. */ reset : function () { this.callsLog = [] } } }) </pre> </body> </html>