Skip to content

Instantly share code, notes, and snippets.

@danbernier
Created November 4, 2015 19:27
Show Gist options
  • Save danbernier/a15b4073bb5ab13b1864 to your computer and use it in GitHub Desktop.
Save danbernier/a15b4073bb5ab13b1864 to your computer and use it in GitHub Desktop.
A Tiny Framework for Automated Tests in Google Apps Script
function allTests(thisFnWrapsAllYourTests) {
var successes = 0;
var failures = [];
var scopes = [];
var msgInScope = function(msg) {
return scopes.concat([msg]).join(": ");
}
var doTheseListsMatch = function(expected, actual) {
if (expected.length != actual.length) {
return false;
}
for (var i = 0; i < expected.length; i++) {
if (expected[i].constructor === Array && actual[i].constructor === Array) {
if (!doTheseListsMatch(expected[i], actual[i])) {
return false;
}
}
else if (expected[i] !== actual[i]) {
return false;
}
}
return true;
}
function runTestAndRecordResult(message, fn) {
try {
if (fn()) {
successes += 1;
} else {
failures.push(msgInScope(message));
}
}
catch(x) {
failures.push(msgInScope(x));
}
}
thisFnWrapsAllYourTests({
describe: function(blockName, thisFnWrapsOneTest) {
scopes.push(blockName);
thisFnWrapsOneTest();
scopes.pop();
},
listMatch: function(expected, actual) {
runTestAndRecordResult("Expected " + expected + ", got " + actual + ".", function() {
return doTheseListsMatch(expected, actual);
});
},
areEqual: function(expected, actual) {
runTestAndRecordResult("Expected " + expected.constructor.name + " " + expected + ", got " + actual.constructor.name + " " + actual + ".", function() {
return expected === actual;
});
},
areClose: function(expected, actual, epsilon) {
if (epsilon === undefined) {
epsilon = 0.001;
}
runTestAndRecordResult("Expected " + expected + " (+/- " + epsilon + "), got " + actual + ".", function() {
return Math.abs(expected - actual) <= epsilon;
});
}
});
var totalTests = successes + failures.length;
alert(successes + " of " + totalTests + " tests passed.\n" + failures.length + " failures.\n" + failures.join("\n"));
}
function add(a, b) {
return a + b;
}
function sum(numbers) {
var sum = 0;
for (var i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum;
}
// This would probably be wired up to a menu item in a Google Spreadsheet:
function runAllTestsFromTheMenu_() {
allTests(function(t) {
t.describe("basic tests", function() {
t.areEqual(1, 1);
});
t.describe("simple functions", function() {
t.describe("add", function() {
t.areEqual(3, add(1, 2));
t.areEqual(7, add(0, 7));
t.areEqual(1, add(10, -9));
});
t.describe("sum", function() {
t.areEqual(10, sum([1,2,3,4]));
t.areEqual(90, sum([20, 30, 40]));
t.areEqual(0, sum([0, -50, 20, 30]));
});
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment