UNPKG

siesta-lite

Version:

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

498 lines (395 loc) 22.7 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-Expectation'>/** </span>@class Siesta.Test.BDD.Expectation This class is the central point for writing assertions in BDD style. Instances of this class can be generated with the {@link Siesta.Test#expect expect} method. Then, calling some method on the instance will create a new assertion in the test. * **Note**, that to negate any assertion, you can use a special property {@link #not}, that contains an expectation instance with the opposite meaning. For example: t.expect(1).toBe(1) t.expect(1).not.toBe(2) t.expect(&#39;Foo&#39;).toContain(&#39;oo&#39;) t.expect(&#39;Foo&#39;).not.toContain(&#39;bar&#39;) */ Class(&#39;Siesta.Test.BDD.Expectation&#39;, { does : [ Siesta.Util.Role.CanGetType ], has : { value : null, isNot : false, <span id='Siesta-Test-BDD-Expectation-property-not'> /** </span> * @property {Siesta.Test.BDD.Expectation} not Another expectation instance with the negated meaning. */ not : null, t : null }, methods : { initialize : function () { if (!this.isNot) this.not = new this.constructor({ isNot : true, t : this.t, value : this.value }) }, process : function (passed, config) { var isNot = this.isNot config = config || {} config.not = config.not || isNot ? &#39;not &#39; : &#39;&#39; config.got = config.hasOwnProperty(&#39;got&#39;) ? config.got : this.value if (config.noGot) delete config.got var assertionName = config.assertionName if (assertionName &amp;&amp; isNot) config.assertionName = assertionName.replace(/^(expect\(.+?\)\.)/, &#39;$1not.&#39;) passed = isNot ? !passed : passed this.t[ passed ? &#39;pass&#39; : &#39;fail&#39; ](null, config) }, <span id='Siesta-Test-BDD-Expectation-method-toBe'> /** </span> * This assertion compares the value provided to the {@link Siesta.Test#expect expect} method with the `expectedValue` argument. * Comparison is done with `===` operator, so it should be used **only with the primitivies** - numbers, strings, booleans etc. * * To deeply compare Date, Arrays and JSON objects in general, use {@link #toEqual} method. * * This method works correctly with the placeholders generated with {@link Siesta.Test#any any} method * * @param {Primitive} expectedValue An expected value */ toBe : function (expectedValue) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.t.compareObjects(this.value, expectedValue, true, true), { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toBe(need)&#39;, need : expectedValue, needDesc : this.isNot ? R.get(&#39;needNotText&#39;) : R.get(&#39;needText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toEqual'> /** </span> * This assertion compares the value provided to the {@link Siesta.Test#expect expect} method with the `expectedValue` argument. * * Comparison works for Date, Array, and JSON objects in general. It is performed &quot;deeply&quot;. * Right now the values should not contain cyclic references. * * This method works correctly with the placeholders generated with {@link Siesta.Test#any any} method * * @param {Mixed} expectedValue An expected value */ toEqual : function (expectedValue) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.t.compareObjects(this.value, expectedValue, true), { descTpl : R.get(&#39;expectText&#39;) +&#39; {got} {!not}&#39; + R.get(&#39;toBeEqualToText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toEqual(need)&#39;, need : expectedValue, needDesc : this.isNot ? R.get(&#39;needNotText&#39;) : R.get(&#39;needText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeNull'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is `null`. */ toBeNull : function () { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.t.compareObjects(this.value, null, true, true), { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeText&#39;) + &#39; null&#39;, assertionName : &#39;expect(got).toBeNull()&#39;, need : null, needDesc : this.isNot ? R.get(&#39;needNotText&#39;) : R.get(&#39;needText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeNaN'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is `NaN`. */ toBeNaN : function () { var value = this.value var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.t.typeOf(value) == &#39;Number&#39; &amp;&amp; value != value, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeText&#39;) + &#39; NaN&#39;, assertionName : &#39;expect(got).toBeNaN()&#39;, need : NaN, needDesc : this.isNot ? R.get(&#39;needNotText&#39;) : R.get(&#39;needText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeDefined'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is not the `undefined` value. */ toBeDefined : function () { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.value !== undefined, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeDefinedText&#39;), assertionName : &#39;expect(got).toBeDefined()&#39; }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeUndefined'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is the `undefined` value. */ toBeUndefined : function (value) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.value === undefined, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeUndefinedText&#39;), assertionName : &#39;expect(got).toBeUndefined()&#39; }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeTruthy'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is &quot;truthy&quot; - evaluates to `true`. * For example - non empty strings, numbers except the 0, objects, arrays etc. */ toBeTruthy : function () { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.value, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeTruthyText&#39;), assertionName : &#39;expect(got).toBeTruthy()&#39; }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeFalsy'> /** </span> * This assertion passes, when value provided to the {@link Siesta.Test#expect expect} method is &quot;falsy&quot; - evaluates to `false`. * For example - empty strings, number 0, `null`, `undefined`, etc. */ toBeFalsy : function () { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(!this.value, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeFalsyText&#39;), assertionName : &#39;expect(got).toBeFalsy()&#39; }) }, <span id='Siesta-Test-BDD-Expectation-method-toMatch'> /** </span> * This assertion passes, when the string provided to the {@link Siesta.Test#expect expect} method matches the regular expression. * * @param {RegExp} regexp The regular expression to match the string against */ toMatch : function (regexp) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); if (this.t.typeOf(regexp) != &#39;RegExp&#39;) throw new Error(&quot;`expect().toMatch()` matcher expects a regular expression&quot;) this.process(new RegExp(regexp).test(this.value), { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toMatchText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toMatch(need)&#39;, need : regexp, needDesc : this.isNot ? R.get(&#39;needNotMatchingText&#39;) : R.get(&#39;needMatchingText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toContain'> /** </span> * This assertion passes in 2 cases: * * 1) When the value provided to the {@link Siesta.Test#expect expect} method is a string, and it contains a passed substring. * 2) When the value provided to the {@link Siesta.Test#expect expect} method is an array (or array-like), and it contains a passed element. * * @param {String/Mixed} element The element of the array or a sub-string */ toContain : function (element) { var value = this.value var t = this.t var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); var passed = false if (t.typeOf(value) == &#39;String&#39;) { this.process(value.indexOf(element) &gt;= 0, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toContainText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toContain(need)&#39;, need : element, needDesc : this.isNot ? R.get(&#39;needStringNotContainingText&#39;) : R.get(&#39;needStringContainingText&#39;) }) } else { // Normalize to allow NodeList, Arguments etc. value = Array.prototype.slice.call(value); for (var i = 0; i &lt; value.length; i++) if (t.compareObjects(element, value[ i ], true)) { passed = true break } this.process(passed, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toContainText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toContain(need)&#39;, need : element, needDesc : this.isNot ? R.get(&#39;needArrayNotContainingText&#39;) : R.get(&#39;needArrayContainingText&#39;) }) } }, <span id='Siesta-Test-BDD-Expectation-method-toBeLessThan'> /** </span> * This assertion passes, when the number provided to the {@link Siesta.Test#expect expect} method is less than the * expected number. * * @param {Number} expectedValue The number to compare with */ toBeLessThan : function (expectedValue) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.value &lt; expectedValue, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeLessThanText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toBeLessThan(need)&#39;, need : expectedValue, needDesc : this.isNot ? R.get(&#39;needGreaterEqualThanText&#39;) : R.get(&#39;needLessThanText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeGreaterThan'> /** </span> * This assertion passes, when the number provided to the {@link Siesta.Test#expect expect} method is greater than the * expected number. * * @param {Number} expectedValue The number to compare with */ toBeGreaterThan : function (expectedValue) { var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(this.value &gt; expectedValue, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeGreaterThanText&#39;) + &#39; {need}&#39;, assertionName : &#39;expect(got).toBeGreaterThan(need)&#39;, need : expectedValue, needDesc : this.isNot ? R.get(&#39;needLessEqualThanText&#39;) : R.get(&#39;needGreaterThanText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toBeCloseTo'> /** </span> * This assertion passes, when the number provided to the {@link Siesta.Test#expect expect} method is approximately equal * the given number. The proximity can be defined as the `precision` argument * * @param {Number} expectedValue The number to compare with * @param {Number} [precision=2] The number of digits after dot (comma) that should be same in both numbers. */ toBeCloseTo : function (expectedValue, precision) { precision = precision != null ? precision : 2 // not sure why we divide the precision by 2, but jasmine does that for some reason var threshold = Math.pow(10, -precision) / 2 var delta = Math.abs(this.value - expectedValue) var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); this.process(delta &lt; threshold, { descTpl : R.get(&#39;expectText&#39;) + &#39; {got} {!not}&#39; + R.get(&#39;toBeCloseToText&#39;) +&#39; {need}&#39;, assertionName : &#39;expect(got).toBeCloseTo(need)&#39;, need : expectedValue, needDesc : this.isNot ? R.get(&#39;needValueNotCloseToText&#39;) : R.get(&#39;needValueCloseToText&#39;), annotation : delta ? R.get(&#39;thresholdIsText&#39;) + threshold : R.get(&#39;exactMatchText&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toThrow'> /** </span> * This assertion passes when the function provided to the {@link Siesta.Test#expect expect} method, throws an exception * during its execution. * * t.expect(function(){ * throw &quot;oopsie&quot;; * }).toThrow()); * */ toThrow : function () { var func = this.value var t = this.t var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); if (t.typeOf(func) != &#39;Function&#39;) throw new Error(&quot;`expect().toMatch()` matcher expects a function&quot;) var e = t.getExceptionCatcher()(func) if (e instanceof t.getTestErrorClass()) //IE uses non-standard &#39;description&#39; property for error msg e = e.message || e.description this.process(e !== undefined, { descTpl : R.get(&#39;expectText&#39;) + &#39; function {!not}&#39; + R.get(&#39;toThrowText&#39;), assertionName : &#39;expect(func).toThrow()&#39;, annotation : e ? (R.get(&#39;thrownExceptionText&#39;) + &#39;: &#39; + Siesta.Util.Serializer.stringify(e)) : R.get(&#39;noExceptionThrownText&#39;), noGot : true }) }, <span id='Siesta-Test-BDD-Expectation-method-toHaveBeenCalled'> /** </span> * This assertion passes, if a spy, provided to the {@link Siesta.Test#expect expect} method have been * called expected number of times. The expected number of times can be provided as the 1st argument and by default * is 1. * * One can also provide the function, spied on, to the {@link Siesta.Test#expect expect} method. * * Examples: * var spy = t.spyOn(obj, &#39;process&#39;) // call the method 2 times obj.process() obj.process() // following 2 calls are equivalent t.expect(spy).toHaveBeenCalled(); t.expect(obj.process).toHaveBeenCalled(); // one can also use exact number of calls or comparison operators t.expect(obj.process).toHaveBeenCalled(2); t.expect(obj.process).toHaveBeenCalled(&#39;&gt;1&#39;); t.expect(obj.process).toHaveBeenCalled(&#39;&lt;=3&#39;); * * See also {@link #toHaveBeenCalledWith} * * @param {Number/String} expectedNumber Expected number of calls. Can be either a number, specifying the exact * number of calls, or a string. In the latter case one can include a comparison operator in front of the number. * */ toHaveBeenCalled : function (expectedNumber) { expectedNumber = expectedNumber != null ? expectedNumber : &#39;&gt;=1&#39; var spy = this.value var t = this.t var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); if (this.typeOf(spy) == &#39;Function&#39;) { if (!spy.__SIESTA_SPY__) throw new Error(R.get(&#39;wrongSpy&#39;)) spy = spy.__SIESTA_SPY__ } if (!(spy instanceof Siesta.Test.BDD.Spy)) throw new Error(R.get(&#39;wrongSpy&#39;)) this.process(t.verifyExpectedNumber(spy.callsLog.length, expectedNumber), { descTpl : R.get(&#39;toHaveBeenCalledDescTpl&#39;), assertionName : &#39;expect(func).toHaveBeenCalled()&#39;, methodName : spy.propertyName || &#39;[function]&#39;, got : spy.callsLog.length, gotDesc : R.get(&#39;actualNbrOfCalls&#39;), need : (this.isNot ? &#39;not &#39; : &#39;&#39;) + expectedNumber, needDesc : R.get(&#39;expectedNbrOfCalls&#39;) }) }, <span id='Siesta-Test-BDD-Expectation-method-toHaveBeenCalledWith'> /** </span> * This assertion passes, if a spy, provided to the {@link Siesta.Test#expect expect} method have been * called at least once with the specified arguments. * * One can also provide the function, spied on, to the {@link Siesta.Test#expect expect} method. * * One can use placeholders, generated with the {@link Siesta.Test.BDD#any any} method to verify the arguments. * * Example: * var spy = t.spyOn(obj, &#39;process&#39;) // call the method 2 times with different arguments obj.build(&#39;development&#39;, &#39;1.0.0&#39;) obj.build(&#39;release&#39;, &#39;1.0.1&#39;) t.expect(spy).toHaveBeenCalledWith(&#39;development&#39;, &#39;1.0.0&#39;); // or t.expect(obj.process).toHaveBeenCalledWith(&#39;development&#39;, t.any(String)); * * See also {@link #toHaveBeenCalled} * * @param {Object} arg1 Argument to a call * @param {Object} arg2 Argument to a call * @param {Object} argN Argument to a call */ toHaveBeenCalledWith : function () { var spy = this.value var t = this.t var R = Siesta.Resource(&#39;Siesta.Test.BDD.Expectation&#39;); if (this.typeOf(spy) == &#39;Function&#39;) { if (!spy.__SIESTA_SPY__) throw new Error(R.get(&#39;wrongSpy&#39;)) spy = spy.__SIESTA_SPY__ } if (!(spy instanceof Siesta.Test.BDD.Spy)) throw new Error(R.get(&#39;wrongSpy&#39;)) var args = Array.prototype.slice.call(arguments) var foundCallWithMatchingArgs = false Joose.A.each(spy.callsLog, function (call) { if (t.compareObjects(call.args, args)) { foundCallWithMatchingArgs = true; return false } }) this.process(foundCallWithMatchingArgs, { descTpl : R.get(&#39;toHaveBeenCalledWithDescTpl&#39;), assertionName : &#39;expect(func).toHaveBeenCalledWith()&#39;, methodName : spy.propertyName, noGot : true }) } } }) </pre> </body> </html>