From abc007f58cd9467277eba2add51cbba2b7af1699 Mon Sep 17 00:00:00 2001 From: Geoff Schmidt Date: Fri, 24 Jan 2014 02:11:45 -0800 Subject: [PATCH] Test to make sure that certain strings don't appear in the output --- tools/selftest.js | 44 +++++++++++++++++++++++++++++++++++++++-- tools/selftests/help.js | 4 ++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tools/selftest.js b/tools/selftest.js index 59af9fe498..d815e915cc 100644 --- a/tools/selftest.js +++ b/tools/selftest.js @@ -77,6 +77,7 @@ _.extend(Matcher.prototype, { var self = this; self.ended = true; self._tryMatch(); + self.buf = ''; }, matchEmpty: function () { @@ -149,7 +150,7 @@ _.extend(Matcher.prototype, { // Maintains a line-by-line merged log of multiple output channels // (eg, stdout and stderr). -var OutputLog = function () { +var OutputLog = function (run) { var self = this; // each entry is an object with keys 'channel', 'text', and if it is @@ -159,6 +160,9 @@ var OutputLog = function () { // map from a channel number name to a string (partially read line // of text on that channel) self.buffers = {}; + + // a Run, exclusively for inclusion in exceptions + self.run = run; }; _.extend(OutputLog.prototype, { @@ -191,6 +195,19 @@ _.extend(OutputLog.prototype, { }); }, + forbid: function (pattern, channel) { + var self = this; + _.each(self.lines, function (line) { + if (channel && channel !== line.channel) + return; + + var match = (pattern instanceof RegExp) ? + (line.text.match(pattern)) : (line.text.indexOf(pattern) !== -1); + if (match) + throw new TestFailure('forbidden-string-present', { run: self.run }); + }); + }, + get: function () { var self = this; return self.lines; @@ -263,7 +280,7 @@ var Run = function (options) { self.stdoutMatcher = new Matcher(self); self.stderrMatcher = new Matcher(self); - self.outputLog = new OutputLog; + self.outputLog = new OutputLog(self); self.exitStatus = undefined; // 'null' means failed rather than exited self.exitFutures = []; @@ -398,6 +415,29 @@ _.extend(Run.prototype, { return this.matchErr(pattern, true); }), + // Assert that 'pattern' (again, a regexp or string) has not + // occurred on stdout at any point so far in this run. Currently + // this works on complete lines, so unlike match() and read(), + // 'pattern' cannot span multiple lines, and furthermore if it is + // called before the end of the program, it may not see text on a + // partially read line. We could lift these restrictions easily, but + // there may not be any benefit since the usual way to use this is + // to call it after expectExit or expectEnd. + forbid: markStack(function (pattern) { + this.outputLog.forbid(pattern, 'stdout'); + }), + + // As forbid(), but for stderr instead of stdout. + forbidErr: markStack(function (pattern) { + this.outputLog.forbid(pattern, 'stderr'); + }), + + // Combination of forbid() and forbidErr(). Forbids the pattern on + // both stdout and stderr. + forbidAll: markStack(function (pattern) { + this.outputLog.forbid(pattern); + }), + // Expect the program to exit without anything further being // printed on either stdout or stderr. expectEnd: markStack(function () { diff --git a/tools/selftests/help.js b/tools/selftests/help.js index 396a1e1d92..41eeac4cca 100644 --- a/tools/selftests/help.js +++ b/tools/selftests/help.js @@ -10,8 +10,8 @@ selftest.define("help", function () { run.match("Commands:"); run.match(/create\s*Create a new project/); run.expectExit(0); - // XXX make sure that 'admin' does not appear - // XXX make sure that hidden commands don't appear + run.forbidAll(/^\s*admin\s/); // no subcommands + run.forbidAll(/^\s*dummy\s/); // no hidden commands }; checkTopLevelHelp(s.run("help"));