summaryrefslogtreecommitdiffstats
path: root/comm/suite/chatzilla/js/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/suite/chatzilla/js/tests
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/suite/chatzilla/js/tests')
-rw-r--r--comm/suite/chatzilla/js/tests/DP.js612
-rw-r--r--comm/suite/chatzilla/js/tests/ircbot.js407
-rw-r--r--comm/suite/chatzilla/js/tests/mingus.js362
-rw-r--r--comm/suite/chatzilla/js/tests/mybot.js21
-rw-r--r--comm/suite/chatzilla/js/tests/test_matchobject.js41
-rw-r--r--comm/suite/chatzilla/js/tests/toys.js35
6 files changed, 1478 insertions, 0 deletions
diff --git a/comm/suite/chatzilla/js/tests/DP.js b/comm/suite/chatzilla/js/tests/DP.js
new file mode 100644
index 0000000000..5320b38c35
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/DP.js
@@ -0,0 +1,612 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Dissociated Press javascript for the jsbot
+ * see: http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?query=dissociated%20press
+ */
+
+DP_DEBUG = false;
+
+if (DP_DEBUG)
+ dpprint = dd;
+else
+ dpprint = (function () {});
+
+function CDPressMachine()
+{
+
+ this.wordPivots = new Object();
+ this.cleanCounter = 0;
+ this.cleanCount = 0;
+
+}
+
+CDPressMachine.CLEAN_CYCLE = 1000; // list will be trimmed after this many
+ // or never if < 1 addPhrase()s
+CDPressMachine.CLEAN_THRESHOLD = 2; // anything <= this will be trimmed
+CDPressMachine.RANDOMIZE_DEPTH = 10; // not used yet
+CDPressMachine.MIN_PHRASE_LENGTH = 3; // requested minimum phrase length
+CDPressMachine.MAX_PHRASE_LENGTH = 8; // requested maximum phrase length
+CDPressMachine.LENGTH_RETRIES = 3 // number of retries per word
+ // (to reach maxlen)
+CDPressMachine.WORD_PATTERN = /[\x21-\x7e]+/; // pattern for words
+
+/**
+ * Adds a phrase to the engine
+ */
+CDPressMachine.prototype.addPhrase =
+function DPM_addPhrase (strPhrase, weight)
+{
+ if (strPhrase == "")
+ return;
+
+ this.cleanCounter++;
+ if ((CDPressMachine.CLEAN_CYCLE >= 1) &&
+ (this.cleanCounter >= CDPressMachine.CLEAN_CYCLE))
+ {
+ dpprint ("** cleaning list");
+
+ this.cleanCounter = 0;
+ this.trimList (CDPressMachine.CLEAN_THRESHOLD);
+ this.cleancount++;
+ }
+
+ strPhrase = strPhrase.toLowerCase();
+
+ /* split the phrase */
+ var aryWordMatches = strPhrase.split (" ");
+ var previousWord = aryWordMatches[aryWordMatches.length - 1];
+ previousWord = previousWord.match(CDPressMachine.WORD_PATTERN);
+ var nextWord = "";
+
+ /* loop through each word */
+ for (var i=-1; i < aryWordMatches.length; i++)
+ {
+ var currentWord = nextWord;
+ var currentWordPivot = this.wordPivots[currentWord];
+
+ if (typeof currentWordPivot == "undefined")
+ currentWordPivot =
+ (this.wordPivots[currentWord] = new CWordPivot (currentWord));
+
+ currentWordPivot.previousList.addLink (previousWord, weight);
+
+ if (i < aryWordMatches.length - 1)
+ {
+ nextWord = aryWordMatches[i + 1];
+ if (nextWord == (String.fromCharCode(1) + "action"))
+ nextWord = escape(nextWord.toUpperCase());
+ else
+ nextWord = nextWord.match(CDPressMachine.WORD_PATTERN);
+
+ if (nextWord == null)
+ nextWord = ""; //this is weak
+
+ currentWordPivot.nextList.addLink (nextWord, weight);
+ }
+ else
+ currentWordPivot.nextList.addLink ("");
+
+ previousWord = currentWord;
+
+ }
+
+}
+
+CDPressMachine.prototype.addPhrases =
+function DPM_addPhrases(phrases)
+{
+
+ for (var i in phrases)
+ this.addPhrase (phrases[i]);
+
+}
+
+/**
+ * Gets a phrase from the engine, starting from seedWord.
+ * if dir is greater than 0, then seedWord will be the first in
+ * the phrase, otherwise it will be the last
+ */
+CDPressMachine.prototype.getPhraseDirected =
+function DPM_getPhraseDirected(seedWord, dir)
+{
+ var word = (typeof seedWord != "undefined") ? seedWord : "";
+ var tempword = word;
+ var rval = "";
+ var c = 0, retry = 0;
+
+ dpprint ("DPM_getPhraseDirected: '" + word + "' " + dir);
+
+ if (typeof this.wordPivots[word] == "undefined")
+ return;
+
+ do
+ {
+ if (typeof this.wordPivots[word] == "undefined")
+ {
+ dd ("** DP Error: Word '" + word + "' is not a pivot **");
+ return;
+ }
+
+ if (dir > 0) // pick a word
+ word= this.wordPivots[word].nextList.getRandomLink().link;
+ else
+ word= this.wordPivots[word].previousList.getRandomLink().link;
+
+ if (word != "") // if it isn't blank
+ {
+ dpprint ("DPM_getPhraseDirected: got word '" + word + "'");
+
+ if (c < CDPressMachine.MIN_PHRASE_LENGTH)
+ retry = 0;
+
+ if (c > CDPressMachine.MAX_PHRASE_LENGTH)
+ if (((dir > 0) && (this.wordPivots[word].nextList.list[""])) ||
+ ((dir <= 0) &&
+ (this.wordPivots[word].previousList.list[""])))
+ {
+ dpprint ("DPM_getPhraseDirected: forcing last word");
+ word="";
+ rval = rval.substring (0, rval.length - 1);
+ break;
+ }
+
+ if (dir > 0)
+ rval += word + " "; // put it in the rslt
+ else
+ rval = word + " " + rval;
+
+ c++; // count the word
+ }
+ else // otherwise
+ {
+ dpprint ("DPM_getPhraseDirected: last word");
+ // if it's too short
+ // and were not out of retrys
+ if ((c < CDPressMachine.MIN_PHRASE_LENGTH) &&
+ (retry++ < CDPressMachine.LENGTH_RETRIES))
+ word = tempword; // try again
+ else
+ // otherwise, we're done
+ rval = rval.substring (0, rval.length - 1);
+ }
+
+ tempword = word;
+
+ } while (word != "");
+
+ rval = unescape (rval);
+
+ return rval;
+
+}
+
+CDPressMachine.prototype.getPhraseForward =
+function DPM_getPhraseForward(firstWord)
+{
+ return this.getPhraseDirected (firstWord, 1)
+}
+
+CDPressMachine.prototype.getPhraseReverse =
+function DPM_getPhraseReverse(lastWord)
+{
+ return this.getPhraseDirected (lastWord, -1)
+}
+
+/**
+ * locates a random pivot by following CDPressMachine.RANDOMIZE_DEPTH
+ * links from |word|.
+ */
+CDPressMachine.prototype.getRandomPivot =
+function DPM_getRandomPivot (word)
+{
+
+ /**
+ * XXXrgg: erm, this is currently pointless, but could be neat later
+ * if max phrase length's were implemented.
+ */
+ if (false)
+ {
+ var depth = parseInt (Math.round
+ (CDPressMachine.RANDOMIZE_DEPTH * Math.random()));
+ word = "";
+ for (var i = 0;
+ i < depth, word =
+ this.wordPivots[word].nextList.getRandomLink().link;
+ i++); /* empty loop */
+
+ }
+
+}
+
+CDPressMachine.prototype.getPhrase =
+function DPM_getPhrase(word)
+{
+ var rval = this.getPhraseContaining (word);
+
+ return rval;
+
+}
+
+/**
+ * Returns a phrase with |word| somewhere in it.
+ */
+CDPressMachine.prototype.getPhraseContaining =
+function DPM_getPhraseContaining(word)
+{
+ if (typeof word == "undefined")
+ word = "";
+ else
+ word = word.toString();
+
+ dpprint ("* DPM_getPhraseContaining: '" + word + "'");
+
+ var rval, spc;
+ var post, pre = this.getPhraseReverse (word);
+ if (word != "")
+ var post = this.getPhraseForward (word);
+
+ dpprint ("* DPM_getPhraseContaining: pre = '" + pre + "' post = '" +
+ post + "'");
+ dpprint ("* DPM_getPhraseContaining: " + (post == "" && pre == ""));
+
+ if (word)
+ {
+ word = unescape (word);
+ spc = " ";
+ }
+ else
+ spc = "";
+
+ if (pre)
+ {
+ if (post)
+ rval = pre + spc + word + spc + post;
+ else
+ rval = pre + spc + word;
+ }
+ else
+ {
+ if (post)
+ rval = word + spc + post;
+ else
+ if (post == "" && pre == "")
+ rval = word;
+ }
+
+ if (rval && (rval.charCodeAt(0) == 1))
+ rval += String.fromCharCode(1);
+
+ dpprint ("* DPM_getPhraseContaining: returning '" + rval + "'");
+
+ return rval;
+
+}
+
+CDPressMachine.prototype.getPhraseWeight =
+function DPM_getPhraseWeight (phrase)
+{
+ var ary = this.getPhraseWeights (phrase);
+ var w = 0;
+
+ while (ary.length > 0)
+ w += ary.pop();
+
+ return w;
+}
+
+CDPressMachine.prototype.getPhraseWeights =
+function DPM_getPhraseWeights (phrase)
+{
+ var words, ary = new Array();
+ var lastword = "";
+ var link, pivot;
+
+ if (!phrase)
+ return ary;
+
+ words = phrase.split (" ");
+
+ for (var i = 0; i < words.length; i++)
+ {
+
+ if (i == 0)
+ {
+ lastWord = "";
+ nextWord = words[i + 1];
+ }
+ else if (i == words.length - 1)
+ {
+ lastWord = words[i - 1];
+ nextWord = "";
+ }
+ else
+ {
+ lastWord = words[i - 1];
+ nextWord = words[i + 1];
+ }
+
+ pivot = this.wordPivots[words[i]];
+
+ if (pivot)
+ {
+ link = pivot.previousList.list[lastWord];
+
+ if (link)
+ ary.push(link.weight);
+ else
+ ary.push(0);
+
+ link = pivot.nextList.list[nextWord];
+
+ if (link)
+ ary.push(link.weight);
+ else
+ ary.push(0);
+ }
+ else
+ {
+ ary.push(0);
+ ary.push(0);
+ }
+
+ }
+
+ return ary;
+
+}
+
+CDPressMachine.prototype.getPivot =
+function DPM_getPivot(word)
+{
+
+ return this.wordPivots[word];
+
+}
+
+CDPressMachine.prototype.trimList =
+function DPM_trimList(threshold)
+{
+ var el;
+ var c;
+
+ for (el in this.wordPivots)
+ {
+ c = this.wordPivots[el].nextList.trimList (threshold);
+ if (c == 0)
+ delete this.wordPivots[el];
+ else
+ {
+ c = this.wordPivots[el].previousList.trimList (threshold);
+ if (c == 0)
+ delete this.wordPivots[el];
+ }
+
+ }
+
+}
+
+CDPressMachine.prototype.getMachineStatus =
+function DPM_getMachineStatus()
+{
+ var o = new Object();
+
+ o.pivotcount = 0;
+ o.linkcount = 0;
+ o.linksperpivot = 0;
+ o.maxweight = 0;
+ o.minweight = Number.MAX_VALUE;
+ o.averageweight = 0;
+ o.cleancounter = this.cleanCounter;
+ o.cleancount = this.cleanCount;
+
+ for (var pivot in this.wordPivots)
+ {
+ o.pivotcount++;
+
+ for (var link in this.wordPivots[pivot].previousList.list)
+ {
+ var l = this.wordPivots[pivot].previousList.list[link];
+
+ o.linkcount++;
+
+ o.maxweight = Math.max (o.maxweight, l.weight);
+ o.minweight = Math.min (o.minweight, l.weight);
+
+ (o.averageweight == 0) ?
+ o.averageweight = l.weight :
+ o.averageweight = (l.weight + o.averageweight) / 2;
+
+ }
+ }
+
+ o.linksperpivot = o.linkcount / o.pivotcount;
+
+ return o;
+
+}
+
+////////////////////////
+function CWordPivot (word)
+{
+
+ dpprint ("* new pivot : '" + word + "'");
+ this.word = word;
+ this.nextList = new CPhraseLinkList(word, "next");
+ this.previousList = new CPhraseLinkList(word, "previous");
+
+}
+
+///////////////////////
+
+function CPhraseLinkList (parentWord, listID)
+{
+
+ if (DP_DEBUG)
+ {
+ this.parentWord = parentWord;
+ this.listID = listID;
+ }
+
+ this.list = new Object();
+
+}
+
+CPhraseLinkList.prototype.addLink =
+function PLL_addLink (link, weight)
+{
+ var existingLink = this.list[link];
+
+ dpprint ("* adding link to '" + link + "' from '" + this.parentWord +
+ "' in list '" + this.listID + "'");
+
+ if (typeof weight == "undefined")
+ weight = 1;
+
+ if (typeof existingLink == "undefined")
+ this.list[link] = new CPhraseLink (link, weight);
+ else
+ if (!(typeof existingLink.adjust == "function"))
+ dd("existingLink.adjust is a '" + existingLink.adjust + "' " +
+ "not a function! link is '" + link +"'");
+ else
+ existingLink.adjust (weight);
+
+}
+
+CPhraseLinkList.prototype.getRandomLink =
+function PLL_getRandomLink ()
+{
+ var tot = 0;
+ var lastMatch = "";
+ var aryChoices = new Array();
+ var fDone = false;
+
+ dpprint ("* PLL_getRandomLink: from '" + this.parentWord + "'");
+
+ for (el in this.list)
+ {
+ tot += this.list[el].weight;
+
+ for (var i = 0; i< aryChoices.length; i++)
+ if (this.list[el].weight <= aryChoices[i].weight)
+ break;
+
+ arrayInsertAt (aryChoices, i, this.list[el]);
+ }
+
+ if (DP_DEBUG)
+ for (var i = 0; i < aryChoices.length; i++)
+ dpprint ("** potential word '" + aryChoices[i].link + "', weight " +
+ aryChoices[i].weight);
+
+ var choice = parseInt (Math.round(((tot - 1) * Math.random()) + 1));
+
+ dpprint ("* PLL_getRandomLink: tot = " + tot + ", choice = " + choice);
+
+ tot = 0;
+ for (i = 0; i < aryChoices.length; i++)
+ {
+ if ((tot += aryChoices[i].weight) >= choice)
+ {
+ lastMatch = aryChoices[i];
+ break;
+ }
+ }
+
+ if (lastMatch == "")
+ lastMatch = aryChoices[aryChoices.length - 1];
+
+ if (!lastMatch)
+ lastMatch = {link: ""}
+
+ dpprint ("* PLL_getRandomLink: returning: " + lastMatch);
+
+ return lastMatch;
+
+}
+
+CPhraseLinkList.prototype.getListWeights =
+function PLL_getListWeights ()
+{
+ var ary = new Array();
+
+ for (var el in this.list)
+ ary.push (this.list[el].weight);
+
+ return ary;
+
+}
+
+CPhraseLinkList.prototype.getListLinks =
+function PLL_getListLinks ()
+{
+ var ary = new Array();
+
+ for (var el in this.list)
+ ary.push (this.list[el].link);
+
+ return ary;
+
+}
+
+CPhraseLinkList.prototype.trimList =
+function PLL_trimList (threshold)
+{
+ var el;
+ var c;
+
+ dpprint ("trimming '" + this.parentWord + "'s list to " + threshold);
+
+ for (el in this.list)
+ {
+ c++;
+
+ if (this.list[el].weight <= threshold)
+ {
+ dpprint ("removing '" + el + "' from '" + this.parentWord + "'s '" +
+ this.listID + "' list, because it's weight is " +
+ this.list[el].weight);
+
+ delete this.list[el];
+ c--;
+ }
+ }
+
+ return c;
+
+}
+
+////////////////////////
+
+function CPhraseLink (link, weight)
+{
+ if (typeof weight == "undefined")
+ this.weight = 1;
+ else
+ this.weight = weight;
+
+ this.link = link;
+
+}
+
+CPhraseLink.prototype.adjust =
+function PL_adjust(weight)
+{
+
+ if ((this.weight += weight) < 1)
+ this.weight = 1;
+
+}
+
+CPhraseLink.prototype.weight =
+function PL_weight ()
+{
+
+ return this.weight;
+
+}
diff --git a/comm/suite/chatzilla/js/tests/ircbot.js b/comm/suite/chatzilla/js/tests/ircbot.js
new file mode 100644
index 0000000000..e3683d034c
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/ircbot.js
@@ -0,0 +1,407 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var LIB_PATH = "../lib/";
+
+bot = new Object();
+bot.ownerPatterns = new Array();
+bot.personality = new Object();
+bot.personality.hooks = new Array();
+bot.prefix = "!js ";
+
+function loadDeps()
+{
+ load(LIB_PATH + "utils.js");
+ load(LIB_PATH + "events.js");
+ load(LIB_PATH + "connection.js");
+ load(LIB_PATH + "http.js");
+ load(LIB_PATH + "dcc.js");
+ load(LIB_PATH + "irc.js");
+ load(LIB_PATH + "irc-debug.js");
+ load(LIB_PATH + "message-manager.js");
+
+ bot.messageManager = new MessageManager();
+
+ load(LIB_PATH + "connection-xpcom.js");
+
+ return true;
+}
+
+// FIXME: Find somewhere better for these guys. //
+function toUnicode(msg, charsetOrView)
+{
+ if (!msg)
+ return msg;
+
+ var charset;
+ if (typeof charsetOrView == "string")
+ charset = charsetOrView;
+ else
+ return msg;
+
+ return bot.messageManager.toUnicode(msg, charset);
+}
+
+function fromUnicode(msg, charsetOrView)
+{
+ if (!msg)
+ return msg;
+
+ var charset;
+ if (typeof charsetOrView == "string")
+ charset = charsetOrView;
+ else
+ return msg;
+
+ return bot.messageManager.fromUnicode(msg, charset);
+}
+// FIXME: END //
+
+
+function initStatic()
+{
+ CIRCNetwork.prototype.INITIAL_NICK = "jsbot";
+ CIRCNetwork.prototype.INITIAL_NAME = "XPJSBot";
+ CIRCNetwork.prototype.INITIAL_DESC = "XPCOM Javascript bot";
+ CIRCNetwork.prototype.INITIAL_CHANNEL = "#jsbot";
+
+ CIRCNetwork.prototype.stayingPower = true;
+ CIRCNetwork.prototype.on433 = my_433;
+ CIRCChannel.prototype.onPrivmsg = my_chan_privmsg;
+ CIRCUser.prototype.onDCCChat = my_user_dccchat;
+ CIRCDCCChat.prototype.onRawData = my_dccchat_rawdata;
+}
+
+/*
+ * One time initilization stuff
+ */
+function init(obj)
+{
+ obj.eventPump = new CEventPump(100);
+
+ obj.networks = new Object();
+ obj.networks["libera.chat"] =
+ new CIRCNetwork("libera.chat", [{name: "libera.chat", port: 6667}],
+ obj.eventPump);
+
+ obj.networks["efnet"] =
+ new CIRCNetwork ("efnet", [{name: "irc.mcs.net", port: 6667},
+ {name: "irc.cs.cmu.edu", port: 6667}],
+ obj.eventPump);
+
+ obj.primNet = obj.networks["efnet"];
+}
+
+/*
+ * Kick off the mainloop for the first time
+ */
+function go()
+{
+ if (!loadDeps())
+ return false;
+
+ // The utils.js formatException relies on localization, we can't. Fix:
+ formatException = function formatException(ex)
+ {
+ if (isinstance(ex, Error) ||
+ ((typeof ex == "object") && ("filename" in ex)))
+ {
+ return [ex.name, ex.message, ex.fileName, ex.lineNumber].join(", ");
+ }
+
+ return String(ex);
+ };
+
+ initStatic();
+ init(bot);
+ if (DEBUG)
+ {
+ /* hook all events EXCEPT server.poll and *.event-end types
+ * (the 4th param inverts the match) */
+ bot.eventPump.addHook([{type: "poll", set: /^(server|dcc-chat)$/},
+ {type: "event-end"}], event_tracer,
+ "event-tracer", true /* negate */);
+ }
+
+ if (typeof initPersonality == "function")
+ initPersonality();
+
+ bot.primNet.connect();
+ rego();
+
+ return true;
+}
+
+/*
+ * If you didn't compile libjs with JS_HAS_ERROR_EXCEPTIONS, any error the
+ * bot encounters will exit the mainloop and drop you back to a shell ("js>")
+ * prompt. You can continue the mainloop by executing this function.
+ */
+function rego()
+{
+ /* mainloop */
+ while (bot.eventPump.queue.length > 0)
+ {
+ bot.eventPump.stepEvents();
+ if (typeof gc == "function")
+ {
+ if ((typeof bot.lastGc == "undefined") ||
+ (Number(new Date()) - bot.lastGc > 60000))
+ {
+ gc();
+ bot.lastGc = Number(new Date());
+ }
+ }
+ }
+ dd("No events to process.");
+
+ return true;
+}
+
+function addOwner(pattern)
+{
+ bot.ownerPatterns.push(pattern);
+}
+
+function userIsOwner(user)
+{
+ if (!user.host)
+ {
+ /* we havn't got any information on this user yet. They havn't spoken
+ * yet, and we havn't /whoi's them yet. Say no for now, but do the
+ * /whois so we'll know for sure next time.
+ */
+ if (user.TYPE == "IRCChanUser")
+ user.parent.parent.sendData("WHOIS " + user.unicodeName + "\n");
+ else
+ user.parent.sendData("WHOIS " + user.unicodeName + "\n");
+ return false;
+ }
+
+ var userString = user.unicodeName + "!" + user.name + "@" + user.host;
+ dd("userIsOwner: checking userString `" + userString + "' against:");
+
+ for (var p in bot.ownerPatterns)
+ {
+ if (userString.search(bot.ownerPatterns[p]) != -1)
+ {
+ dd(String(bot.ownerPatterns[p]) + " passed.");
+ return true;
+ }
+ else
+ {
+ dd(String(bot.ownerPatterns[p]) + " fails.");
+ }
+ }
+
+ return false;
+}
+
+function psn_isAddressedToMe(e)
+{
+ if (!e.server)
+ return false;
+
+ if ((e.type.search(/privmsg|ctcp-action/)) || (e.set != "channel"))
+ return false;
+
+ var msg = e.decodeParam(2);
+
+ if (msg.indexOf(bot.prefix) == 0)
+ return false;
+
+ /*
+ dd ("-*- checking to see if message '" + msg + "' is addressed to me.");
+ */
+
+ var regex = new RegExp("^\\s*" + e.server.me.unicodeName + "\\W+(.*)", "i");
+ var ary = msg.match(regex);
+
+ //dd ("address match: " + ary);
+
+ if (ary != null)
+ {
+ e.statement = ary[1];
+ return true;
+ }
+
+ //XXXgijs: Shouldn't this be in mingus.js?
+ bot.personality.dp.addPhrase(msg);
+ return false;
+}
+
+function psn_onAddressedMsg(e)
+{
+
+ bot.eventPump.onHook(e, bot.personality.hooks);
+ return false;
+}
+
+bot.personality.addHook =
+function psn_addhook(pattern, f, name, neg, enabled)
+{
+ if (pattern instanceof RegExp)
+ pattern = {statement: pattern};
+
+ return bot.eventPump.addHook(pattern, f, name, neg, enabled,
+ bot.personality.hooks);
+}
+
+function bot_eval(e, script)
+{
+ try
+ {
+ var v = eval(script);
+ }
+ catch (ex)
+ {
+ e.replyTo.say(e.user.unicodeName + ": " + String(ex));
+ return false;
+ }
+
+ if (typeof v != "undefined")
+ {
+ if (v != null)
+ v = String(v);
+ else
+ v = "null";
+
+ var rsp = e.user.unicodeName + ", your result is,";
+
+ if (v.indexOf("\n") != -1)
+ rsp += "\n";
+ else
+ rsp += " ";
+
+ e.replyTo.say(rsp + v);
+ }
+}
+
+/*
+ * The following my_* are attached to their proper objects in the init()
+ * function. This is because the CIRC* objects are not defined at load time
+ * (they get defined when loadDeps() loads the irc library) and so connecting
+ * them here would cause an error.
+ */
+
+/*
+ * What to do when a privmsg is received on a channel
+ */
+function my_chan_privmsg(e)
+{
+ var user = e.user;
+ var msg = e.decodeParam(2);
+ if ((msg.indexOf(bot.prefix) == 0) && userIsOwner(user))
+ {
+ /* if last char is a continuation character, then... */
+ if (msg[msg.length - 1] == "\\")
+ {
+ user.accumulatedScript = msg.substring(bot.prefix.length,
+ msg.length - 1);
+ return false; // prevent other hooks from processing this...
+ }
+ else
+ {
+ return bot_eval(e, msg.substring(bot.prefix.length,
+ msg.length));
+ }
+ }
+ else if ((typeof(user.accumulatedScript) != "undefined") &&
+ userIsOwner(user))
+ /* if we were accumulating a message, add here,
+ * and finish if not ends with '\'. */
+ {
+ var lastLine = (msg[msg.length - 1] != "\\");
+ var line = msg.substring(0, msg.length - (lastLine ? 0 : 1));
+ user.accumulatedScript += line;
+ if (lastLine)
+ {
+ var script = user.accumulatedScript;
+ delete user.accumulatedScript;
+ return bot_eval(e, script);
+ }
+ }
+}
+
+/*
+ * What to do when a dcc chat request reaches a user object
+ */
+function my_user_dccchat(e)
+{
+ if (!e.user.canDCC)
+ {
+ e.user.notice("\01DCC REJECT CHAT chat\01");
+ return false;
+ }
+
+ var c = new CIRCDCCChat(bot.eventPump);
+
+ if (!c.connect(e.user.host, e.port))
+ {
+ e.user.notice("\01DCC REJECT CHAT chat\01");
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * What to do when our requested nickname is in use
+ */
+function my_433(e)
+{
+ if (e.params[2] != CIRCNetwork.prototype.INITIAL_NICK)
+ {
+ /* server didn't like the last nick we tried, probably too long.
+ * not much more we can do, bail out. */
+ e.server.disconnect();
+ }
+
+ CIRCNetwork.prototype.INITIAL_NICK += "_";
+ e.server.sendData("nick " + CIRCNetwork.prototype.INITIAL_NICK + "\n");
+}
+
+/*
+ * What to do when raw data is received on a dcc chat connection
+ */
+function my_dccchat_rawdata(e)
+{
+ try
+ {
+ var v = eval(e.data);
+ }
+ catch (ex)
+ {
+ this.say(String(ex));
+ return false;
+ }
+
+ if (typeof v != "undefined")
+ {
+ if (v != null)
+ v = String(v);
+ else
+ v = "null";
+
+ this.say(v);
+ }
+}
+
+/*
+ * Wrapper around CHTTPDoc to make is simpler to use
+ */
+function loadHTTP(host, path, onComplete)
+{
+ var htdoc = new CHTTPDoc(host, path);
+
+ htdoc.onComplete = onComplete;
+ htdoc.get(bot.eventPump);
+
+ return htdoc;
+}
+
+
+
diff --git a/comm/suite/chatzilla/js/tests/mingus.js b/comm/suite/chatzilla/js/tests/mingus.js
new file mode 100644
index 0000000000..2590ed919e
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/mingus.js
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+bot.personality.guessPrefixes = ["I guess ", "maybe ", "probably ", "I think ",
+ "could be that ", "", ""];
+bot.personality.guessActionPrefixes = ["guesses ", "postulates ", "figures ",
+ "tries ","pretends ", "", ""];
+
+function initMingus()
+{
+ //XXX You should add the owner(s) of the bot here. You can do so with a
+ // regular expression which matches their hostmask, like so:
+ // addOwner(/rginda.*!.*@.*netscape\.com$/i);
+
+ bot.primNet = bot.networks["libera.chat"];
+
+ load("DP.js");
+ CIRCNetwork.prototype.INITIAL_NICK = "mingus";
+ CIRCNetwork.prototype.INITIAL_NAME = "mingus";
+ CIRCNetwork.prototype.INITIAL_DESC = "real men do it with prototypes";
+ CIRCNetwork.prototype.INITIAL_CHANNEL = "#chatzilla";
+
+ CIRCChannel.prototype.onJoin =
+ function my_chan_join(e)
+ {
+ if (userIsOwner(e.user))
+ e.user.setOp(true);
+ };
+
+ bot.eventPump.addHook(psn_isAddressedToMe, psn_onAddressedMsg,
+ "addressed-to-me-hook");
+ bot.personality.dp = new CDPressMachine();
+ /*
+ bot.personality.dp.addPhrase ("I am " +
+ CIRCNetwork.prototype.INITIAL_NICK +
+ ", hear me roar.");
+ */
+ bot.personality.dp.addPhrase("\01ACTION is back.");
+
+ /* dp hooks start */
+
+ var f = function(e)
+ {
+ var catchall = (e.hooks[e.hooks.length - 1].name == "catchall");
+ var answer = "";
+
+ if (catchall)
+ {
+ var ary = e.statement.split(" ");
+ for (var i = 0; i < 3; i++)
+ {
+ var randomElem = getRandomElement(ary);
+ answer = bot.personality.dp.getPhraseContaining(randomElem);
+ if (answer)
+ break;
+ }
+ }
+
+ if (!answer)
+ answer = bot.personality.dp.getPhrase();
+
+ if (answer[answer.length - 1] == "\01")
+ {
+ if (answer[0] != "\01")
+ {
+ if (catchall)
+ {
+ var prefes = bot.personality.guessActionPrefes;
+ answer = "\01ACTION " + getRandomElement(prefes) + answer;
+ }
+ else
+ {
+ answer = "\01ACTION " + answer;
+ }
+ }
+ }
+ else
+ {
+ if (!answer)
+ answer = "I don't know anything";
+
+ if (catchall)
+ {
+ answer = getRandomElement(bot.personality.guessPrefixes) +
+ answer;
+ }
+ }
+
+ if (answer[0] != "\01")
+ e.replyTo.say(e.user.unicodeName + ", " + answer);
+ else
+ e.replyTo.say(answer);
+
+ return false;
+ };
+
+/* first hook added is last checked */
+ bot.personality.addHook(/.*/i, f, "catchall");
+ bot.personality.addHook(/speak$/i, f, "speak");
+ bot.personality.addHook(/talk$/i, f, "hook");
+ bot.personality.addHook(/say something$/i, f, "say-something");
+
+ f = function(e)
+ {
+ var subject = e.matchresult[1].match(CDPressMachine.WORD_PATTERN);
+ if (subject == null)
+ subject = "";
+ else
+ subject = subject.toString();
+
+ var escapedSubject = escape(subject.toLowerCase());
+ var answer = bot.personality.dp.getPhraseContaining(escapedSubject);
+
+ if (!answer)
+ answer = "I don't know anything about " + e.matchresult[1];
+
+ if (answer.charCodeAt(0) != 1)
+ e.replyTo.say(e.user.unicodeName + ", " + answer);
+ else
+ e.replyTo.say(answer);
+
+ return false;
+ };
+
+ bot.personality.addHook(/speak about (\S+)/i, f);
+ bot.personality.addHook(/talk about (\S+)/i, f);
+ bot.personality.addHook(/say something about (\S+)/i, f);
+
+ f = function(e)
+ {
+ var answer = bot.personality.dp.getPhraseContaining("%01ACTION");
+
+ if (!answer)
+ answer = "I can't do a thing.";
+
+ e.replyTo.say(answer);
+
+ return false;
+ };
+
+ bot.personality.addHook(/do something/i, f);
+
+ f = function(e)
+ {
+ var ary = bot.personality.dp.getPhraseWeights(e.matchresult[1]);
+ var c = bot.personality.dp.getPhraseWeight(e.matchresult[1]);
+
+ e.replyTo.say(e.user.unicodeName + ", that phrase weighs " +
+ c + ": " + ary);
+
+ return false;
+ };
+
+ bot.personality.addHook(/weigh (.+)/i, f);
+
+ f = function(e)
+ {
+ var word = e.matchresult[1].toLowerCase();
+ var pivot = bot.personality.dp.getPivot(word);
+ var result = "";
+
+ if (pivot)
+ {
+ var list, w, l;
+
+ list = pivot.previousList;
+
+ w = list.getListWeights();
+ l = list.getListLinks();
+
+ if (w.length != l.length)
+ e.replyTo.say("warning: previous list mismatched.");
+
+ for (var i = 0; i < Math.max(w.length, l.length); i++)
+ result += ("`" + l[i] + "'" + w[i] + " ");
+
+ if (result.length > 250)
+ result += "\n";
+
+ result += ( "[" + word + "]" );
+
+ if (result.length > 250)
+ result += "\n";
+
+ list = pivot.nextList;
+
+ w = list.getListWeights();
+ l = list.getListLinks();
+
+ if (w.length != l.length)
+ e.replyTo.say("warning: next list mismatched.");
+
+ for (var i = 0; i < Math.max(w.length, l.length); i++)
+ result += (" `" + l[i] + "'" + w[i]);
+ }
+ else
+ {
+ result = "- [" + word + "] -";
+ }
+
+ e.replyTo.say(result);
+
+ return false;
+ };
+
+ bot.personality.addHook(/pivot (.*)/i, f);
+
+/* dp hooks end */
+
+ f = function(e)
+ {
+ print("I can hear you.");
+ e.replyTo.say(e.user.unicodeName + ", yes, I am.");
+
+ return false;
+ };
+
+ bot.personality.addHook(/are you alive(\?)?/i, f);
+
+
+ f = function(e)
+ {
+ if (!userIsOwner(e.user))
+ {
+ e.replyTo.say("nope.");
+ return;
+ }
+
+ chan = e.matchresult[1];
+
+ if (chan.charAt(0) != "#")
+ chan = "#" + chan;
+
+ e.server.sendData("join " + chan + "\n");
+
+ return false;
+ };
+
+ bot.personality.addHook(/join\s+(\S+)\.*/i, f);
+
+ f = function(e)
+ {
+ if (!userIsOwner(e.user))
+ {
+ e.channel.say("nope.");
+ return false;
+ }
+
+ chan = e.matchresult[1];
+
+ if (chan.charAt(0) != "#")
+ chan = "#" + chan;
+
+ e.server.sendData("part " + chan + "\n");
+
+ return false;
+ };
+
+ bot.personality.addHook(/part\s+(\S+)\.*/i, f);
+ bot.personality.addHook(/leave\s+(\S+)\.*/i, f);
+
+ f = function (e)
+ {
+ e.replyTo.say("mmmmmmm. Thanks " + e.user.unicodeName + ".");
+ return false;
+ };
+
+ bot.personality.addHook(/botsnack/i, f);
+
+ f = function(e)
+ {
+ e.replyTo.act("blushes");
+ return false;
+ };
+
+ bot.personality.addHook(/you rock/i, f);
+
+ f = function(e)
+ {
+ if (e.matchresult[1] == "me")
+ e.replyTo.act("hugs " + e.user.unicodeName);
+ else
+ e.replyTo.act("hugs " + e.matchresult[1]);
+ return false;
+ };
+
+ bot.personality.addHook(/hug (.*)/i, f);
+
+ f = function(e)
+ {
+ if (e.matchresult[1] == "me")
+ e.replyTo.say(e.user.unicodeName + ", :*");
+ else
+ e.replyTo.say(e.matchresult[1] + ", :*");
+ return false;
+ };
+
+ bot.personality.addHook(/kiss (\w+)/, f);
+
+ f = function (e)
+ {
+ e.replyTo.say(e.user.unicodeName + ", I'll try :(");
+ return false;
+ };
+
+ bot.personality.addHook
+ (/(shut up)|(shaddup)|(be quiet)|(keep quiet)|(sssh)|(stfu)/i, f);
+
+ f = function(e)
+ {
+ if (!userIsOwner(e.user))
+ {
+ e.replyTo.say("No.");
+ }
+ else
+ {
+ for (var n in bot.networks)
+ bot.networks[n].quit("Goodnight.");
+ }
+ return false;
+ };
+
+ bot.personality.addHook(/(go to bed)|(go to sleep)|(sleep)/i, f);
+
+ f = function(e)
+ {
+ e.replyTo.say(":)");
+ return false;
+ };
+
+ bot.personality.addHook
+ (/(smile)|(rotfl)|(lmao)|(rotflmao)|(look happy)|(you(.)?re smart)/i, f);
+/* (/(smile)|(rotfl)|(lmao)|(rotflmao)|(you(.)?re funny)|(look happy)|(you(.)?re smart)/i, f); */
+
+ f = function(e)
+ {
+ e.replyTo.say(":(");
+ return false;
+ };
+
+ bot.personality.addHook(/(frown)|(don(.)?t like you)|(look sad)/i, f);
+
+ f = function(e)
+ {
+ e.replyTo.say(">:|");
+ return false;
+ };
+
+ bot.personality.addHook(/(look mad)|(beat you up)/i, f);
+
+ f = function(e)
+ {
+ e.replyTo.say(":/");
+ return false;
+ };
+
+ bot.personality.addHook(/(look confused)|(i like windows)/i, f);
+}
+
diff --git a/comm/suite/chatzilla/js/tests/mybot.js b/comm/suite/chatzilla/js/tests/mybot.js
new file mode 100644
index 0000000000..260943b3c1
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/mybot.js
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+if (typeof escape == "undefined")
+ escape = unescape = function (s) {return s;}
+
+
+function runMyBot()
+{
+ load ("ircbot.js");
+ go();
+}
+
+function initPersonality()
+{
+ load ("mingus.js");
+ initMingus();
+}
diff --git a/comm/suite/chatzilla/js/tests/test_matchobject.js b/comm/suite/chatzilla/js/tests/test_matchobject.js
new file mode 100644
index 0000000000..c44380a366
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/test_matchobject.js
@@ -0,0 +1,41 @@
+
+function test_matchObject()
+{
+ var f = true;
+
+ obj1 = {foo:"hey", bar:"ho"}
+ obj2 = {a:"1", b:"2"}
+
+ p1 = {foo:"hey"}
+ p2 = {bar:"ho"}
+ p3 = {a:"1"}
+ p4 = {b:"2"}
+
+ /* true, single pattern, and it matches */
+ f &= matchObject (obj1, p1);
+ /* false, single pattern matches, negated */
+ f &= !matchObject (obj1, p1, true);
+
+ /* false, single pattern doesn't match */
+ f &= !matchObject (obj1, p3);
+ /* true, single pattern doesn't match, negated */
+ f &= matchObject (obj1, p3, true);
+
+ /* true, p1 matches */
+ f &= matchObject (obj1, [p1, p3]);
+ /* false, p1 matches, negated */
+ f &= !matchObject (obj1, [p1, p3], true);
+
+ /* true, both paterns match */
+ f &= matchObject (obj2, [p3, p4]);
+ /* false, both patterns match, negated */
+ f &= !matchObject (obj2, [p3, p4], true);
+
+ /* false, neither pattern matches */
+ f &= !matchObject (obj1, [p3, p4]);
+ /* true, neither pattern matches, negated */
+ f &= matchObject (obj1, [p3, p4], true);
+
+ return Boolean(f); /* you've got to find any problems by hand :) */
+
+} \ No newline at end of file
diff --git a/comm/suite/chatzilla/js/tests/toys.js b/comm/suite/chatzilla/js/tests/toys.js
new file mode 100644
index 0000000000..a9fd7f7e9c
--- /dev/null
+++ b/comm/suite/chatzilla/js/tests/toys.js
@@ -0,0 +1,35 @@
+
+function rainbow(str)
+{
+ str = String(str);
+ var c = str.length;
+ var rv = "";
+
+ for (var i = 0; i < c; i++)
+ {
+ var color = randomRange (2, 6);
+ rv += unescape ("%03" + color + str[i]);
+ }
+
+ return rv;
+
+}
+
+function fade(str)
+{
+ var colors = new Array(1, 14, 10, 15, 0);
+ var cIndex = 0;
+ var msg = "";
+ for (var i = 0; i < str.length; i++)
+ {
+ msg += "%03" + colors[cIndex] + str[i];
+ if ((++cIndex) == 5)
+ {
+ cIndex = 0;
+ }
+ }
+
+ return unescape(msg);
+
+ }
+