UNPKG

beast-test

Version:

A package that allow for JUnit like TestCases. Very Robust Test Driven Development Framework

609 lines (492 loc) 20.4 kB
// Generated by CoffeeScript 1.7.1 (function() { var Result, TestCase, TestComponent, TestResult, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; Result = (function() { function Result(passed, message) { this.passed = passed; this.message = message; } return Result; })(); /* This class is the {TestResult} of when a {TestCase} is run. This is stored inside {TestCase.result} */ TestResult = (function() { /* @nodoc */ function TestResult(testClass, name, message, result, position) { this.testClass = testClass; this.name = name; this.message = message; this.result = result; this.position = position; this['class'] = this.testClass; } /* @property [String] The Object name that extended the TestCase Class */ TestResult.prototype.testClass = null; /* @property [String] The name of the method that was being tested */ TestResult.prototype.name = null; /* @property [String] The message from the result of the Test */ TestResult.prototype.message = null; /* @property [Integer] The type of the Result @see {TestCase.passed}, {TestCase.warning}, {TestCase.failed} */ TestResult.prototype.result = null; /* @property [Integer] The position of the assert Function for the specific method being tested */ TestResult.prototype.position = null; return TestResult; })(); if (typeof module !== "undefined") { if (typeof module.exports !== "undefined") { module.exports.TestResult = TestResult; } } TestComponent = (function() { function TestComponent() {} TestComponent.prototype._trueTest = function(a) { if (a !== true) { return new Result(false, "failed to assert that " + (this.stringObject(a)) + " is true"); } else { return new Result(true, "" + (this.stringObject(a)) + " is equal to true"); } }; TestComponent.prototype._same = function(a, b) { if (a === b) { return new Result(true, "asserted that " + (this.stringObject(a)) + " is " + (this.stringObject(b))); } else { return new Result(false, "failed to assert that " + (this.stringObject(a)) + " is " + (this.stringObject(b))); } }; TestComponent.prototype._equals = function(a, b) { if (a instanceof Array && b instanceof Array) { return this._arrayEquals(a, b); } return this._same(a, b); }; TestComponent.prototype._arrayEquals = function(a, b) { var k, result, v; if (a.length === b.length) { for (k in a) { v = a[k]; if (!((result = this._equals(v, b[k])) && result.passed)) { return new Result(false, "failed to assert [" + (this.stringObject(a)) + "] is equal to [" + (this.stringObject(b)) + "] because property[" + (this.stringObject(k)) + "] is not equal"); } } } return new Result(true, "asserted that [" + (this.stringObject(a)) + "] is equal to [" + (this.stringObject(b)) + "]"); }; TestComponent.prototype._isFunction = function(f) { if (typeof f === "function") { return new Result(true, "assert that " + (this.stringObject(f)) + " is a function"); } else { return new Result(false, "failed to assert that " + (this.stringObject(f)) + " is a function"); } }; /* This method will test if the value is equal to true @param value [Boolean] */ TestComponent.prototype.assertTrue = function(value) { var result; result = this._trueTest(value); if (result.passed) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, result.message, TestCase.failed, TestCase.testAssert++)); } }; /* This will test if a value is null @param value [Object,String,Number,Boolean] */ TestComponent.prototype.assertNull = function(value) { if (value === null) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert " + value + " as null", TestCase.failed, TestCase.testAssert++)); } }; /* This will test if an Object is not null @param value [Object,String,Number,Boolean] */ TestComponent.prototype.assertNotNull = function(value) { if (value !== null) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert " + value + " as not null", TestCase.failed, TestCase.testAssert++)); } }; /* This will test if two values are equal. This will do a deep Object Comparison on Objects and Arrays. Be careful of Objects that might contain circular references. The Application will handle it just fine but it will result in a warning. These Object will not neccesarily be equal @param test [Object,String,Number,Boolean] @param value [Object,String,Number,Boolean] */ TestComponent.prototype.assertEquals = function(test, value) { if (test instanceof Array && value instanceof Array) { return this.assertArrayEquals(test, value); } if (test instanceof Object && value instanceof Object) { return this.assertObjectEquals(test, value); } if (test === value) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert \"" + test + "\" equal to \"" + value + "\"", TestCase.failed, TestCase.testAssert++)); } }; /* This will test if two arrays are equal. This will not do a deep object test on the array. It will only check the first level of the array @param array1 [Array] @param array2 [Array] */ TestComponent.prototype.assertArrayEquals = function(array1, array2) { var result; result = this._arrayEquals(array1, array2); if (!result.passed) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, result.message, TestCase.failed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, result.message, TestCase.passed, TestCase.testAssert++)); } }; /* This will check if a value is a function. This can be useful with callbacks testing. @param func [Function] */ TestComponent.prototype.assertFunction = function(func) { var result; result = this._isFunction(func); if (result.passed) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, result.message, TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, result.message, TestCase.failed, TestCase.testAssert++)); } }; /* This is essential the same as {TestCase#assertEquals}. This is just a more reader friendly form that is better at documenting your intention. @param obj1 [Object] @param obj2 [Object] */ TestComponent.prototype.assertObjectEquals = function(obj1, obj2) { var e, result; try { result = this.deepObjectCompare(obj1, obj2); } catch (_error) { e = _error; if (e instanceof RangeError) { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "Warning - Object may have circular reference, may or may not be equal", TestCase.warning, TestCase.testAssert++)); return; } else { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, e.message, TestCase.failed, TestCase.testAssert++)); return; } } if (!result.passed) { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert property[" + result.key + "] is equal, \"" + result.value.test + "\" not \"" + result.value.value + "\"", TestCase.failed, TestCase.testAssert++)); } else { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } }; /* @nodoc */ TestComponent.prototype.deepObjectCompare = function(test, value) { var cmp, key, result; result = {}; cmp = []; for (key in test) { cmp[key] = key; } for (key in value) { cmp[key] = key; } for (key in cmp) { result.key = key; result.value = { "test": test[key], "value": value[key] }; if (typeof test[key] === "object" && typeof value[key] === "object") { if (!this.deepObjectCompare(test[key], value[key]).passed) { result.passed = false; return result; } } else if (typeof test[key] === "object" && typeof value[key] === "object") { if (!this.deepObjectCompare(test[key], value[key]).passed) { result.passed = false; return result; } } else if (test[key] !== value[key]) { result.passed = false; return result; } } result.passed = true; return result; }; /* This will test if two values are similar. This is mainly for primitive values when comparing a string and a number. When used on a object it is essentially the same as {TestCase#assertSame}. This will also ignore casing when comparing strings @example 5=='5' #true 'PizzaMan' == 'pizzaman' #true @param test [Object,String,Number,Boolean] @param value [Object,String,Number,Boolean] */ TestComponent.prototype.assertSimilar = function(test, value) { if (typeof test === "string" && typeof value === "string") { if (test.toLowerCase() === value.toLowerCase()) { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert \"" + test + "\" of type [" + (typeof test) + "] is similar to \"" + value + "\" of type [" + (typeof value) + "]", TestCase.failed, TestCase.testAssert++)); } return; } if (test == value) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert \"" + test + "\" of type [" + (typeof test) + "] is similar to \"" + value + "\" of type [" + (typeof value) + "]", TestCase.failed, TestCase.testAssert++)); } }; /* This will check if two objects are the same objects. It will also test if two primitives are equal. @param test [Object,String,Number,Boolean] @param value [Object,String,Number,Boolean] */ TestComponent.prototype.assertSame = function(test, value) { if (test === value) { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "passed", TestCase.passed, TestCase.testAssert++)); } else { return TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "failed to assert \"" + test + "\" is the exact same \"" + value + "\"", TestCase.failed, TestCase.testAssert++)); } }; TestComponent.prototype.stringObject = function(o) { var element, str, strpack, _i, _len; str = ""; strpack = []; if (o instanceof Array) { if (o.length < 10) { for (_i = 0, _len = o.length; _i < _len; _i++) { element = o[_i]; strpack.push("" + (this.stringObject(element))); } str = strpack.join(", "); } else { str = "Array" + 0 + "..." + o.length; } str = "[" + str + "]"; } else if (o instanceof Object) { str = "[" + o.constructor.name + ": properties:" + o.length + "]"; } else if (typeof o === "string") { str = "\"" + o + "\""; } else if (typeof o === "number") { str = "" + o; } else if (typeof o === "function") { str = "[" + f.name + ": arguments " + f.length + "]"; } else { str = "" + (o.toString()); } return str; }; return TestComponent; })(); /* This class provides an extremely readable testing framework for testing with CoffeeScript and Javascript in General. It was built using CoffeeScript. You must keep this header in all copy of this Source Code. @author Shavauhn Gabay */ TestCase = (function(_super) { var ready; __extends(TestCase, _super); ready = false; /* @param auto [Boolean] if set to false test will not automatically run. Test can be run with the {TestCase#run} method @return [TestCase] */ function TestCase(auto) { this.auto = auto != null ? auto : true; TestCase.count++; if (this.auto) { this.run(); } } TestCase.count = 0; TestCase.result = []; /* @nodoc */ TestCase.prototype.prepare = function() { var property, _results; for (property in this) { if (property === "base") { ready = true; } } _results = []; for (property in this) { if (property === "reset" && typeof this[reset] === "function") { _results.push(ready = ready && true); } else { _results.push(void 0); } } return _results; }; /* This method is used to run the Test. The test will be executed and the results will be stored inside {TestCase.result} array. */ TestCase.prototype.run = function() { var e, property; if (typeof TestCase.start_t === "undefined") { TestCase.start_t = Date.now(); } else { TestCase.start_t = Math.min(Date.now(), TestCase.start_t); } this.prepare(); if (!ready) { return; } for (property in this) { if (property.slice(0, 5).toLowerCase() === "_test" || property.slice(0, 4).toLowerCase() === "test") { TestCase.testAssert = 1; TestCase.currentClassName = this.constructor.name; TestCase.currentName = property; try { this.base(); } catch (_error) { e = _error; TestCase.result.push(new TestResult(TestCase.currentClassName, "base", "Exception " + e.constructor.name + ": " + e.message, TestCase.failed, 0)); break; } try { if (this.base() instanceof Array) { this[property].apply(this, this.base()); } else { this[property].call(this, this.base()); } } catch (_error) { e = _error; if (e instanceof RangeError) { TestCase.result.push(new TestResult(TestCase.currentClassName, TestCase.currentName, "Exception " + e.constructor.name + ": " + e.message, TestCase.failed, TestCase.testAssert)); } else { throw e; } continue; } } } return TestCase.end_t = Date.now(); }; /* This will symbolize that a test has passed */ TestCase.passed = 1; /* This will symbolize that a test has passed but with a warning */ TestCase.warning = 0; /* This will symbolize that a test has failed */ TestCase.failed = -1.; /* This can be used to get the HTML Summary of the Results @return [String] */ TestCase.getHTMLResult = function() { TestCase.nl = "<br/>"; TestCase.tab = "&nbsp;&nbsp;&nbsp;"; return TestCase.print(); }; /* This will get the result but without any HTML code inside the string @return [String] */ TestCase.getResult = function() { TestCase.nl = "\n"; TestCase.tab = "\t"; return TestCase.print(); }; /* This is used in the print format of {TestCase.getResult} and {TestCase.getHTMLResult}. This value is overwritten each time those functions are run. If you want to add your own spacing for need to overwrite and then call {TestCase.print} */ TestCase.nl = "\n"; /* This is used in the print format of {TestCase.getResult} and {TestCase.getHTMLResult}. This value is overwritten each time those functions are run. If you want to add your own spacing for need to overwrite and then call {TestCase.print} */ TestCase.tab = "\t"; /* This will contain all of the results, after a test has been run */ TestCase.result = []; /* You can create your own custom print by overwriting {TestCase.format} and changing the {TestCase.nl} and {TestCase.tab} and calling {TestCase.print} */ TestCase.print = function() { var failCount, passedCount, result, string, warningCount, _i, _len, _ref; failCount = 0; warningCount = 0; passedCount = 0; string = ""; _ref = TestCase.result; for (_i = 0, _len = _ref.length; _i < _len; _i++) { result = _ref[_i]; if (result.result === TestCase.passed) { passedCount++; } else if (result.result === TestCase.warning) { warningCount++; string += TestCase.format(result); } else if (result.result === TestCase.failed) { failCount++; string += TestCase.format(result); } } TestCase.total_t = TestCase.end_t - TestCase.start_t; TestCase.seconds = parseInt(TestCase.total_t / 1000); TestCase.ms = TestCase.total_t % 1000; return string += "Test Complete " + passedCount + "/" + TestCase.result.length + " passed, " + warningCount + "/" + TestCase.result.length + " warnings, " + failCount + "/" + TestCase.result.length + " failed" + TestCase.nl + "Total time " + TestCase.seconds + "s " + TestCase.ms + "ms"; }; /* This method is used to format the code that is generated from the results. You can override this method to create a different format if you want to. @param result [TestResult] @return [String] */ TestCase.format = function(result) { var nl, tab; nl = TestCase.nl; tab = TestCase.tab; if (result.result === TestCase.passed) { return ""; } else if (result.result === TestCase.warning) { return "" + result["class"] + "@" + result.name + nl + tab + result.message + ", on assert # " + result.position + nl + nl; } else if (result.result === TestCase.failed) { return "" + result["class"] + "@" + result.name + nl + tab + result.message + ", on assert # " + result.position + nl + nl; } }; return TestCase; })(TestComponent); if (typeof module !== "undefined") { if (typeof module.exports !== "undefined") { module.exports.TestCase = TestCase; } } }).call(this);