/*global console, test, throws, equal, fail, notEqual, expect, require, ok, QUnit, RiTa, RiString, RiGrammar, RiMarkov, RiLexicon */ var runtests = function () { if (typeof YAML == 'undefined') YAML = require('yamljs'); var SILENT = true, WITHOUT_YAML = typeof YAML == 'undefined'; QUnit.module("RiGrammar", { setup: function () {}, teardown: function () {}, }); var sentenceGrammarJSON = { "": " .", "": " ", "": " | [.1]", "": "a [.1] | the", "": "woman | man", "": "shoots" }; var sentenceGrammarJSON2 = { "": " .", "": " ", "": ["a [.1]", "the"], "": [" [.1]", ""], "": ["woman", "man"], "": "shoots" }; var sentenceGrammarYAML = " : .\n: \n : | [.1]\n: woman | man\n: a [.1] | the\n: shoots"; var sentenceGrammarYAML2 = " : .\n: \n : \n - \n - [.1]\n: \n - woman\n - man\n: \n - a [.1] \n - the\n: shoots"; var sentenceGrammarYAML3 = "--- : a [.1] | the\n#I am a comment\n: woman | man\n: \n: .\n: shoots\n: | [.1]\n: >\n This is\n my very long string\n that wraps three lines\n"; var sentenceGrammars = [sentenceGrammarJSON, sentenceGrammarJSON2, sentenceGrammarYAML, sentenceGrammarYAML2]; //var sentenceGrammarFiles = [ "sentence1.json", "sentence2.json", "sentence1.yaml", "sentence2.yaml" ]; //var haikuGrammarFiles = [ "haikuGrammar.json", "haikuGrammar2.json", "haikuGrammar.yaml", "haikuGrammar2.yaml" ]; if (WITHOUT_YAML) { console.warn("[WARN] YAML parser not found -- skipping all YAML tests"); sentenceGrammars = [sentenceGrammarJSON, sentenceGrammarJSON2]; //sentenceGrammarFiles = [ "sentence1.json", "sentence2.json" ]; //haikuGrammarFiles = [ "haikuGrammar.json", "haikuGrammar2.json" ]; } test("testGetGrammar", function () { var rg = new RiGrammar(sentenceGrammarJSON); var rg2 = new RiGrammar(sentenceGrammarJSON2); deepEqual(rg, rg2) var e = "\n ' .' [1]\n\n ' ' [1]\n\n '' [1]\n ' ' [.1]\n\n 'a' [.1]\n 'the' [1]\n\n 'woman' [1]\n 'man' [1]\n\n 'shoots' [1]"; //console.log(rg.getGrammar()); equal(rg.getGrammar(), e); }); test("testYaml", function () { if (!WITHOUT_YAML) { ok(YAML.parse(sentenceGrammarYAML)); ok(YAML.parse(sentenceGrammarYAML2)); ok(YAML.parse(sentenceGrammarYAML3)); } else ok(1); }); test("testInit", function () { var rg = RiGrammar(); ok(rg._rules); // empty ok(typeof rg._rules[''] === 'undefined'); ok(typeof rg._rules[''] === 'undefined'); var rg1 = RiGrammar(sentenceGrammarJSON); ok(rg1._rules); ok(rg1._rules['']); ok(rg1._rules['']); var rg2 = RiGrammar(JSON.stringify(sentenceGrammarJSON)); ok(rg2._rules); ok(rg2._rules['']); ok(rg2._rules['']); var rg3 = RiGrammar(sentenceGrammarJSON2); ok(rg3._rules); ok(rg3._rules['']); ok(rg3._rules['']); deepEqual(rg1, rg2); deepEqual(rg2, rg3); deepEqual(rg1, rg3); if (!WITHOUT_YAML) { // TEST the YAML grammars var rg4 = RiGrammar(sentenceGrammarYAML); ok(rg4._rules); ok(rg4._rules['']); ok(rg4._rules['']); var rg5 = RiGrammar(sentenceGrammarYAML2); ok(rg5._rules); ok(rg5._rules['']); ok(rg5._rules['']); deepEqual(rg1, rg4); deepEqual(rg1, rg5); } var BAD = ["{a : 1}", "hello"]; for (var i = 0; i < BAD.length; i++) { throws(function () { try { RiGrammar(BAD[i]); fail("no exception"); } catch (e) { throw e; } }); } }); test("testLoad", function () { var rg = new RiGrammar(); ok(rg._rules); ok(typeof rg._rules[''] === 'undefined'); ok(typeof rg._rules[''] === 'undefined'); rg.load(JSON.stringify(sentenceGrammarJSON)); ok(rg._rules); ok(typeof rg._rules[''] !== 'undefined'); ok(typeof rg._rules[''] !== 'undefined'); rg.load(JSON.stringify(sentenceGrammarJSON2)); ok(rg._rules); ok(typeof rg._rules[''] !== 'undefined'); ok(typeof rg._rules[''] !== 'undefined'); }); test("testAddRule", function () { var rg = new RiGrammar(); rg.addRule("", ""); ok(rg._rules[""]); ok(rg.hasRule("")); rg.addRule("", "", .3); ok(rg._rules[""]); ok(rg.hasRule("")); }); test("testExpand()", function () { for (var j = 0; j < sentenceGrammars.length; j++) { var rg = new RiGrammar(sentenceGrammars[j]); for (var i = 0; i < 10; i++) ok(rg.expand()); } var rg = new RiGrammar(); rg.addRule("", "pet"); equal(rg.expand(), "pet"); rg.addRule("", "pet", 1); equal(rg.expand(), "pet"); rg.addRule("", "pet", 2); equal(rg.expand(), "pet"); rg.reset(); rg.addRule("", "", 1); rg.addRule("", "dog", 1); equal(rg.expand(), "dog"); ///////////////////////////////////////////////////////////////// rg.reset(); rg.addRule("", "", 1); rg.addRule("", "cat", .4); rg.addRule("", "dog", .6); rg.addRule("", "boy", .2); ok(rg.hasRule("")); var found1 = false, found2 = false, found3 = false; for (var i = 0; i < 100; i++) { var res = rg.expand(); ok(res === ("cat") || res === ("dog") || res === ("boy")); if (res === ("cat")) found1 = true; else if (res === ("dog")) found2 = true; else if (res === ("boy")) found3 = true; } ok(found1 && found2 && found3); // found all ///////////////////////////////////////////////////////////////// rg.reset(); rg.addRule("", "", 1); rg.addRule("", "cat | dog | boy"); ok(rg.hasRule("")); found1 = false; found2 = false; found3 = false; for (var i = 0; i < 100; i++) { var res = rg.expand(); ok(res === ("cat") || res === ("dog") || res === ("boy")); if (res === ("cat")) found1 = true; else if (res === ("dog")) found2 = true; else if (res === ("boy")) found3 = true; } ok(found1 && found2 && found3); // found all ///////////////////////////////////////////////////////////////// rg.reset(); rg.addRule("", "pet", 1); equal(rg.expand(), "pet"); rg.reset(); rg.addRule("", "the ran.", 1); rg.addRule("", "dog", .7); for (var i = 0; i < 10; i++) equal(rg.expand(), "the dog ran."); rg.reset(); rg.addRule("", "the .", 1); rg.addRule("", "dog", .7); rg.addRule("", "cat", .3); var d = 0, c = 0; for (var i = 0; i < 100; i++) { var r = rg.expand(); if (r === "the dog.") d++; if (r === "the cat.") c++; } ok(d > 50); // d + "" ok(d < 90); // d + "" ok(c > 10); // g + "" ok(c < 50); // g + "" }); /*test("testExpandOld()", function() { var s, rg = new RiGrammar(); rg.addRule("", "pet"); equal(s=rg.expand(), "pet"); //console.log(s); rg.reset(); rg.addRule("", "").addRule("", "dog"); equal(s=rg.expand(), "dog"); rg.reset(); rg.addRule("", "the ran."); rg.addRule("", "dog"); s = rg.expand(); equal(s, "the dog ran."); rg.reset(); rg.addRule("", ""); rg.addRule("", "cat", .4); rg.addRule("", "dog", .6); rg.addRule("", "boy", .2); ok(rg.hasRule("")); var found1 = false, found2 = false, found3 = false; for ( var i = 0; i < 20; i++) { var res = rg.expand(); ok(res === "cat" || res === 'dog' || res === 'boy'); if (res === "cat") found1 = true; else if (res === "dog") found2 = true; else if (res === "boy") found3 = true; } ok(found1); ok(found2); ok(found3); var fail = false; for ( var i = 0; i < 20; i++) { var res = rg.expand() if (!res) fail = true; } ok(!fail); rg.reset(); rg.addRule("", "pet"); equal(rg.expand(), "pet"); rg.reset(); rg.addRule("", "the ran.", 1); rg.addRule("", "dog", .7); for (var i = 0; i < 10; i++) equal(rg.expand(), "the dog ran."); rg.reset(); rg.addRule("", "the ."); rg.addRule("", "dog", .7); rg.addRule("", "cat", .3); var d = 0, g = 0; for ( var i = 0; i < 100; i++) { var r = rg.expand(); if (r == 'the dog.') d++; if (r == 'the cat.') g++; } // delta=20% ok(d > 50 && d < 100, d + "% (dog =~ 70%)"); ok(d < 90 && d > 0, d + "% (dog =~ 70%)"); ok(g > 10 && g < 100, g + "% (cat =~ 30%)"); ok(g < 50 && g > 0, g + "% (cat =~ 30%)"); });*/ test("testExpandFrom", function () { var rg = new RiGrammar(); rg.reset(); rg.addRule("", ""); rg.addRule("", " | "); rg.addRule("", "hawk | crow"); rg.addRule("", "dog"); equal(rg.expandFrom(""), "dog"); for (var i = 0; i < 100; i++) { var res = rg.expandFrom(""); ok(res === "hawk" || res === 'crow'); } throws(function () { try { rg.expandFrom("wrongName") } catch (e) { throw e; } }); }); test("testExpandFrom(Weighted)", function () { var rg = new RiGrammar(); rg.reset(); rg.addRule("", ""); rg.addRule("", " [9] | "); rg.addRule("", "hawk"); rg.addRule("", "dog [2]"); equal(rg.expandFrom(""), "dog"); var hawks = 0, dogs = 0; for (var i = 0; i < 100; i++) { var res = rg.expandFrom(""); ok(res === "hawk" || res === 'dog'); if (res == "dog") dogs++; if (res == "hawk") hawks++; } ok(hawks > dogs * 2); }); test("testHasRule", function () { var g = [new RiGrammar(sentenceGrammarJSON), new RiGrammar(sentenceGrammarJSON2)]; for (var i = 0; i < g.length; i++) { var rg = g[i]; ok(rg.hasRule("")); ok(!rg.hasRule("start")); rg.reset(); ok(!rg.hasRule("start")); rg.addRule("", ""); ok(rg.hasRule("")); ok(!rg.hasRule("rule1")); rg.reset(); rg.addRule("", "cat", .4); rg.addRule("", "dog", .6); rg.addRule("", "boy", .2); ok(rg.hasRule("")); ok(!rg.hasRule("rule1")); ok(!rg.hasRule("badname")); rg.reset(); rg.addRule("rule1", ""); ok(!rg.hasRule("")); ok(rg.hasRule("rule1")); ok(!rg.hasRule(null)); ok(!rg.hasRule(undefined)); ok(!rg.hasRule(1)); } }); test("testReset", function () { var rg = new RiGrammar(); ok(rg._rules); rg.load(JSON.stringify(sentenceGrammarJSON)); rg.reset(); deepEqual(rg._rules, {}); deepEqual(rg, RiGrammar()); }); test("testRemoveRule", function () { var rg1 = new RiGrammar(sentenceGrammarJSON); ok(rg1._rules['']); ok(rg1._rules['']); rg1.removeRule(''); ok(!rg1._rules['']); rg1.removeRule(''); ok(!rg1._rules['']); rg1.removeRule(''); rg1.removeRule('bad-name'); rg1.removeRule(null); rg1.removeRule(undefined); rg1 = new RiGrammar(sentenceGrammarJSON2); ok(rg1._rules['']); ok(rg1._rules['']); rg1.removeRule(''); ok(!rg1._rules['']); rg1.removeRule(''); ok(!rg1._rules['']); rg1.removeRule(''); rg1.removeRule('bad-name'); rg1.removeRule(null); rg1.removeRule(undefined); }); test("testPrint", function () { var rg = new RiGrammar(); rg.reset(); rg.addRule("", " | ", 1); rg.addRule("", "the of ...", 1); rg.addRule("", "the of the were ...", 1); rg.addRule("", " | ", 1); rg.addRule("", "hawks | crows", 1); rg.addRule("", "dogs", 1); rg.addRule("", "cries | screams | falls", 1); //rg.print(); ok(typeof rg.print === 'function'); }); test("testExpandWith", function () { var rg = new RiGrammar(); rg.addRule("", "the | the of the "); rg.addRule("", " | "); rg.addRule("", "hawk | crow | screamer"); rg.addRule("", "dog"); rg.addRule("", "cries | screams | falls"); var r = rg.expandWith("screams", ""); var str = "", missed = false; for (var i = 0; i < 100; i++) { var r = rg.expandWith("screams", ""); if (r.indexOf("screams") < 1) { str = r; // console.log("error: " + r); missed = true; } } equal(missed, false); str = "", missed = false; for (var i = 0; i < 100; i++) { var r = rg.expandWith("dog", ""); if (r.indexOf("dog") < 1) { str = r; // console.log("error: " + r); missed = true; } } equal(missed, false); //equal("TODO: MORE TESTS HERE"); }); test("testSpecialChars", function () { var rg, res, s s = "{ \"\": \"hello | name\" }"; rg = new RiGrammar(s); res = rg.expand(); //console.log(res); ok(res === "hello | name"); s = "{ \"\": \"hello: name\" }"; rg = new RiGrammar(s); res = rg.expand(); ok(res === "hello: name"); s = "{ \"\": \"“hello!”\" }"; rg = new RiGrammar(s); //rule = rg.getRule(""); //ok(rule==="“hello!”"); //ok("fails b/c of editor?"); //res = rg.expand(); //console.log(res+'=“hello!”'); // ok(res==='“hello!”'); // fails bc of editor s = "{ \"\": \"<start>\" }"; rg = new RiGrammar(s); res = rg.expand(); //console.log(res); ok(res === ""); s = "{ \"\": \"I don`t want it.\" }"; rg = new RiGrammar(s); res = rg.expand(); //console.log(res); ok(res === "I don`t want it."); s = "{ \"\": \"'I really don't'\" }"; rg = new RiGrammar(s); res = rg.expand(); ok(res === "'I really don't'"); s = "{ \"\": \"hello | name\" }"; rg = new RiGrammar(s); for (var i = 0; i < 10; i++) { res = rg.expand(); ok(res === "hello" || res === "name"); } }); test("testExecIgnore", function () { var rg = new RiGrammar(); // do nothing rg.execDisabled = false; rg.addRule("", " | "); rg.addRule("", "the were 'adj()'"); rg.addRule("", "the of the 'adj()' "); rg.addRule("", " | "); rg.addRule("", "hawk | crow"); rg.addRule("", "dog"); rg.addRule("", "cries | screams | falls"); for (var i = 0; i < 10; i++) { var res = rg.expand(); //console.log(i+") "+res); ok(res != null && res.length > 0); ok(res.indexOf("'adj()'") > -1); } rg.reset(); rg.addRule("", " | "); rg.addRule("", "the were `adj()'"); rg.addRule("", "the of the `adj()' "); rg.addRule("", " | "); rg.addRule("", "hawk | crow"); rg.addRule("", "dog"); rg.addRule("", "cries | screams | falls"); for (var i = 0; i < 10; i++) { var res = rg.expand(); //console.log(i+") "+res); ok(res != null && res.length > 0); ok(res.indexOf("`adj()'") > -1); } rg.reset(); rg.addRule("", " | "); rg.addRule("", "the were `nofun()`"); rg.addRule("", "the of the `nofun()` "); rg.addRule("", " | "); rg.addRule("", "hawk | crow"); rg.addRule("", "dog"); rg.addRule("", "cries | screams | falls"); var tmp = RiTa.SILENT; RiTa.SILENT = true; for (var i = 0; i < 5; i++) { var res = rg.expand(); //console.log(i+") "+res); ok(res != null && res.length > 0 && res.indexOf("`nofun()`") > -1); } for (var i = 0; i < 5; i++) { var res = rg.expand(this); //console.log(i+") "+res); ok(res != null && res.length > 0 && res.indexOf("`nofun()`") > -1); } RiTa.SILENT = tmp; }); test("testExecRE", function () { var str, res, re = RiGrammar.EXEC_PATT; str = "`hello()`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello()`", ""]); if (!SILENT) console.log("==========================="); str = "`hello(and)`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello(and)`", ""]); if (!SILENT) console.log("==========================="); str = "`hello('and')`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello('and')`", ""]); if (!SILENT) console.log("==========================="); str = '`hello("and")`'; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", '`hello("and")`', ""]); if (!SILENT) console.log("==========================="); str = "and `hello()` there"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello()`", " there"]); if (!SILENT) console.log("==========================="); str = "and `hello()` there `you()`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello()`", " there `you()`"]); if (!SILENT) console.log("==========================="); str = "and `hello()`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello()`", ""]); if (!SILENT) console.log("==========================="); str = "`hello()` there `you()`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello()`", " there `you()`"]); if (!SILENT) console.log("==========================="); str = "`hello();`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello();`", ""]); if (!SILENT) console.log("==========================="); str = "`hello(and);`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello(and);`", ""]); if (!SILENT) console.log("==========================="); str = "`hello('and');`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello('and');`", ""]); if (!SILENT) console.log("==========================="); str = '`hello("and");`'; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", '`hello("and");`', ""]); if (!SILENT) console.log("==========================="); str = "and `hello();` there"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello();`", " there"]); if (!SILENT) console.log("==========================="); str = "and `hello();` there `you();`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello();`", " there `you();`"]); if (!SILENT) console.log("==========================="); str = "and `hello();`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["and ", "`hello();`", ""]); if (!SILENT) console.log("==========================="); str = "`hello();` there `you();`"; res = re.exec(str); for (var i = 0; i < res.length; i++) if (!SILENT) console.log("'" + res[i] + "'"); res.splice(0, 1); deepEqual(res, ["", "`hello();`", " there `you();`"]); }); test("testExec1", function () { temp = function () { // global: for exec testing return Math.random() < 0.5 ? 'hot' : 'cold'; } var rg = new RiGrammar(); rg.execDisabled = false; ok(rg); //if (typeof module!=='undefined') { // for node-issue #9 rg.addRule("", " | "); rg.addRule("", "the were `temp()`"); rg.addRule("", "the of the `temp()` "); rg.addRule("", " | "); rg.addRule("", "hawk | crow"); rg.addRule("", "dog"); rg.addRule("", "cries | screams | falls"); for (var i = 0; i < 10; i++) { // TODO: fails in NODE ?? // The "this" value passed to eval must be the global object from which eval originated ? var res = rg.expand(); //console.log(res); ok(res && !res.match("`") && res.match(/(hot|cold)/)); } //} }); test("testExec2", function () { var newruleg = { '': 'The chased the `newrule("")`.', '': 'dog | cat | mouse', '': 'rhino' }; newrule = function (n) { // global: for exec testing return ''; } var rg = new RiGrammar(newruleg); rg.execDisabled = false; ok(rg); //if (typeof module == 'undefined') { // for node-issue #9 for (var i = 0; i < 10; i++) { var res = rg.expand(); //console.log(res); ok(res && res.match(/ chased the rhino\./g)); } //} }); test("testExec3", function () { var newruleg2 = { '': 'The chased the `staticFun()`.', '': 'dog | cat | mouse', }; function staticFun() { // global: for exec testing return "rhino"; } var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); for (var i = 0; i < 10; i++) { var res = rg.expand(staticFun); //console.log(res); ok(res && res.match(/ chased the rhino\./g)); } }); test("testExec4", function () { var newruleg2 = { '': 'The chased the `RiTa.pluralize(\'\')`.', '': 'dog | cat | mouse', }; var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); for (var i = 0; i < 10; i++) { var res = rg.expand(); //console.log(res); ok(res && res.match(/(dogs|cats|mice)\./g)); } }); // Create the frog callback locally, but don't pass // a closure into expand; should FAIL to expand. test("testExec5", function () { var frog = function () { return 'frog'; }; var newruleg2 = { '': 'The chased the `frog()`.', '': 'dog | cat | mouse', }; var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); RiTa.SILENT = true; // ignore max-iterations warning var res = rg.expand(); // expand should fail ok(res && res.endsWith(" chased the `frog()`.")); RiTa.SILENT = false; }); // Create the frog callback locally, and pass // in a local closure; should succeed. test("testExec6", function () { var frog = () => 'frog'; var newruleg2 = { '': 'The chased the `frog()`.', '': 'dog | cat | mouse', }; var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); var res = rg.expand(function (str) { return eval(str); }); // console.log(res); ok(res && res.match(/frog\./g)); }); // Test a rule with a dynamic weighting test("testExecDynamicWeighting", function () { var weight = 1, noweight = 0; var newruleg2 = { '': 'cat [weight] | dog [noweight]' }; var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); var res = rg.expand(function (str) { return eval(str); }); ok(res && res.indexOf("cat") != -1); }); // Test a rule with a dynamic weighting, no value test("testExecDynamicWeighting2", function () { var weight = 1, newruleg2 = { '': 'cat [weight] | dog [unknownWeight]' }; var rg = new RiGrammar(newruleg2); rg.execDisabled = false; ok(rg); var pre = RiTa.SILENT; RiTa.SILENT = true; var res = rg.expand(function (str) { return eval(str); }); RiTa.SILENT = pre; ok(res && res.indexOf("cat") != -1); }); // Test specifying a random number generator test("testRNG", function () { var newrule = { '': 'cat | dog ' }; var rg = new RiGrammar(newrule, function () { return 0.25; }); ok(rg); var res = rg.expand(function (str) { return eval(str); }); ok(res && res.indexOf("cat") != -1); rg = new RiGrammar(newrule, function () { return 0.75; }); ok(rg); res = rg.expand(function (str) { return eval(str); }); ok(res && res.indexOf("dog") != -1); }); test("testExecArgs", function () { var rl = RiLexicon(); function isNumeric(n) { return !isNaN(parseFloat(n)) && isFinite(n); } // globals for exec testing newrule = function (n) { return ''; } adj = function(num) { return RiLexicon().randomWord("jj", num) }; getFloat = function() { return Math.random() }; var res, i, rg = new RiGrammar(); rg.execDisabled = false; ok(rg); //if (typeof module == 'undefined') { // for node-issue #9 rg.addRule("", "`getFloat()`"); for (i = 0; i < 10; i++) { res = rg.expandFrom("", this); //console.log(res); ok(res && res.length && isNumeric(res)); } rg.reset(); rg.addRule("", "`adj(2)`"); for (i = 0; i < 10; i++) { res = rg.expandFrom("", this); //console.log(res); ok(res && res.length && rl.isAdjective(res)); } //} }); }; if (typeof exports != 'undefined') runtests();