function loadScript(url, callback) { var head = document.head; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; script.onreadystatechange = callback; script.onload = callback; head.appendChild(script); } var testsPass=undefined; var TestSuite; var totalTests = 0; var totalTestsPassed = 0; class describe { constructor(testname) { this.testname=testname this.beforecb = ()=>{}; this.cb = undefined; this.totaltests = 0; this.passedtests = 0; this.starttime = 0; console.log(this.testname) this.beforeEach = (cb)=>{ this.beforecb = cb return this } this.it = (checkname,cb)=>{ this.starttime = new Date().getTime() console.log("->"+checkname) this.beforecb() this.cb=cb; this.cb() return this } this.showResults = () =>{ console.log("==============") console.log("TEST RESULTS: "+TestSuite.passedtests+" passed, "+(TestSuite.totaltests-TestSuite.passedtests)+" failed, "+TestSuite.totaltests+" total") console.log("==============") } } } function expect(testval1,testval2,name) { if (testval1!==testval2) { console.log(" Test Failed! Expected "+testval2+" but got "+testval1+". ("+(new Date().getTime()-TestSuite.starttime)+"ms)"+((name)?` - ${name}`:"")) TestSuite.totaltests++ totalTests++ testsPass=false } else { TestSuite.totaltests++ TestSuite.passedtests++ totalTests++ totalTestsPassed++ console.log(" Test Passed!"+" ("+(new Date().getTime()-TestSuite.starttime)+"ms)"+((name)?` - ${name}`:"")) } } function AllBlankSpaces(level) { for (var x=0;x{ resetGame() }) .it("Blank level exists.",()=>{ expect(AllBlankSpaces(LEVEL0),true) }) .it("Bot moves to the right initially.",()=>{ expect(function(){ gameGrid=createGrid(5,5) placeBot(0,2) runBot(true) if (BOT_X===1&&BOT_Y===2) { return true } else { return false } }(),true) }) .it("Bot obeys conveyor belt rules",()=>{ expect(function(){ loadLevel(LEVEL1,0,2) for (var i=0;i<11;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===1) { return true } else { return false } }(),true) }) .it("Bot obeys branch rules",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) for (var i=0;i<3;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===3) { return true } else { return false } }(),true) }) .it("Bot obeys branch rules with different colored tape.",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) BOT_TAPE = "B" for (var i=0;i<3;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===1) { return true } else { return false } }(),true) }) .it("Bot tape is reduced by 1 when passing through a branch.",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) for (var i=0;i<3;i++) {runBot(true)} if (BOT_TAPE.length===1&&BOT_TAPE[0]==="B") { return true } else { return false } }(),true) }) .it("Bot tape is reduced by 1 when passing through a different branch.",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) BOT_TAPE = "B" for (var i=0;i<3;i++) {runBot(true)} if (BOT_TAPE.length===0) { return true } else { return false } }(),true) }) .it("Bot obeys writer movement rules",()=>{ expect(function(){ loadLevel(LEVEL3,0,2) for (var i=0;i<3;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===3) { return true } else { return false } }(),true) }) .it("Bot obeys writer tape rules - Has correct tape when appending",()=>{ expect(function(){ loadLevel(LEVEL3,0,2) for (var i=0;i<3;i++) {runBot(true)} if (BOT_TAPE.length===3&&BOT_TAPE[2]==="R") { return true } else { return false } }(),true) }) .it("Bot obeys writer tape rules - Has correct tape when overwriting",()=>{ expect(function(){ loadLevel(LEVEL3,0,1) BOT_TAPE="BR" for (var i=0;i<2;i++) {runBot(true)} if (BOT_TAPE.length===2&&BOT_TAPE[0]==="R") { return true } else { return false } }(),true) }) .it("Bot goes forward if no color matched.",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) BOT_TAPE = [{color:YELLOW}] for (var i=0;i<2;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===2) { return true } else { return false } }(),true) }) .it("Bot tape is unaffected if no color matched.",()=>{ expect(function(){ loadLevel(LEVEL2,0,2) BOT_TAPE = [{color:YELLOW}] for (var i=0;i<2;i++) {runBot(true)} if (BOT_TAPE.length===1) { return true } else { return false } }(),true) }) .it("Bot goes right when approaching a double belt (Left->Right) from the left",()=>{ expect(function(){ loadLevel(LEVEL4,0,2) for (var i=0;i<2;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===2) { return true } else { return false } }(),true) }) .it("Bot goes down when approaching a double belt (Up->Down) from the top",()=>{ expect(function(){ loadLevel(LEVEL4,1,1) BOT_DIR=DOWN for (var i=0;i<2;i++) {runBot(true)} if (BOT_X===1&&BOT_Y===3) { return true } else { return false } }(),true) }) .it("Bot goes right when approaching a double belt (Left->Right) from the Right",()=>{ expect(function(){ loadLevel(LEVEL4,2,2) BOT_DIR=LEFT for (var i=0;i<2;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===2) { return true } else { return false } }(),true) }) .it("Bot goes up when approaching a double belt (Down->Up) from the Bottom",()=>{ expect(function(){ loadLevel(LEVEL4,2,4) BOT_DIR=UP for (var i=0;i<2;i++) {runBot(true)} if (BOT_X===2&&BOT_Y===2) { return true } else { return false } }(),true) }) .it("Convert Number to Tape function works as expected. 0 bits=R, 1 bits=B",()=>{ expect(ConvertNumberToTape(4),"BRR","4=100=\"BRR\"") expect(ConvertNumberToTape(24),"BBRRR","24=11000=\"BBRRR\"") expect(ConvertNumberToTape(167),"BRBRRBBB","167=10100111=\"BRBRRBBB\"") }).showResults() TestSuite = new describe("Stage 1") TestSuite .beforeEach(()=>{ resetGame() }) .it("Stage 1 has a level",()=>{ expect(STAGE1.level===undefined,false,"Is defined") expect(Array.isArray(STAGE1.level),true,"Is an array") expect(STAGE1.level.length>0,true,"Cannot be empty") }) .it("Stage 1 has a name",()=>{ expect(STAGE1.name===undefined,false,"Is defined") expect(typeof(STAGE1.name),"string","Is a string") expect(STAGE1.name.length>0,true,"Cannot be blank") }) .it("Stage 1 has an objective",()=>{ expect(STAGE1.objective===undefined,false,"Is defined") expect(typeof(STAGE1.objective),"string","Is a string") expect(STAGE1.objective.length>0,true,"Cannot be blank") }) .it("Stage 1 has a starting position",()=>{ expect(STAGE1.start===undefined,false,"Is defined") expect(typeof(STAGE1.start),"object","Is an object") expect(STAGE1.start.x===undefined,false,"Must have an X coordinate") expect(STAGE1.start.y===undefined,false,"Must have a Y coordinate") }) .it("Stage 1 has an acceptance condition",()=>{ expect(STAGE1.accept===undefined,false) expect(typeof(STAGE1.accept),"function") }) .it("loadStage sets up stage 1",()=>{ loadStage(STAGE1) expect(gameGrid.length===STAGE1.level.length,true,"Height of stage is equal") expect(gameGrid[0].length===STAGE1.level[0].length,true,"Width of stage is equal") }) .it("current stage set to stage 1",()=>{ loadStage(STAGE1) expect(gameStage===STAGE1,true) }) .it("accept all bots for stage 1.",()=>{ loadStage(STAGE1) expect(gameStage.accept(""),true,"Expect true for \"\"") expect(gameStage.accept("RB"),true,"Expect true for RB") expect(gameStage.accept("BRBR"),true,"Expect true for BRBR") }) .it("bot fails at the start.",()=>{ loadStage(STAGE1) runBot(true) expect(gameState===REVIEWING,true) }) .it("When TESTING state is on, the game should test the current level for cases expecting to pass, but fail and create 3 of them if possible.",()=>{ loadStage(STAGE1) expect(BOT_QUEUE.length===0,true,"Bot queue should be empty.") generateBotQueue() expect(BOT_QUEUE.length===0&&gameState!==TESTING,true,"Bot queue should not be modified while state is not TESTING") gameState=TESTING generateBotQueue() expect(BOT_QUEUE.length===3,true,"There should be 3 bots in queue for an unbuilt level, as all bots are supposed to pass.") }) .it("A stage should have an Exit.",()=>{ loadStage(STAGE1) var hasAnExit=()=>{ for (var y=0;y{ loadStage(STAGE1) placeBot(3,2) runBot(true) expect(gameState===FINISH,true) }) .it("Run a TESTING state to see if an acceptable player-built level has no bots in queue.",()=>{ loadStage(STAGE1) gameGrid=[ [{},{},{},{},{},], [{},{},{},{},{},], [{},{...BELTRIGHT},{...BELTRIGHT},{...BELTRIGHT},{type:"EXIT"},], [{},{},{},{},{},], [{},{},{},{},{},], ] expect(BOT_QUEUE.length===0,true,"Bot queue should be empty.") gameState=TESTING generateBotQueue() //console.log(BOT_QUEUE) expect(BOT_QUEUE.length===0,true,"There should be 0 bots in queue for a good level, as all bots are supposed to pass.") }) .showResults() TestSuite = new describe("Stage 2") TestSuite .beforeEach(()=>{ resetGame() }) .it("Stage 2 has a level",()=>{ expect(STAGE2.level===undefined,false,"Is defined") expect(Array.isArray(STAGE2.level),true,"Is an array") expect(STAGE2.level.length>0,true,"Cannot be empty") }) .it("Stage 2 has a name",()=>{ expect(STAGE2.name===undefined,false,"Is defined") expect(typeof(STAGE2.name),"string","Is a string") expect(STAGE2.name.length>0,true,"Cannot be blank") }) .it("Stage 2 has an objective",()=>{ expect(STAGE2.objective===undefined,false,"Is defined") expect(typeof(STAGE2.objective),"string","Is a string") expect(STAGE2.objective.length>0,true,"Cannot be blank") }) .it("Stage 2 has a starting position",()=>{ expect(STAGE2.start===undefined,false,"Is defined") expect(typeof(STAGE2.start),"object","Is an object") expect(STAGE2.start.x===undefined,false,"Must have an X coordinate") expect(STAGE2.start.y===undefined,false,"Must have a Y coordinate") }) .it("Stage 2 has an acceptance condition",()=>{ expect(STAGE2.accept===undefined,false) expect(typeof(STAGE2.accept),"function") }) .it("loadStage sets up Stage 2",()=>{ loadStage(STAGE2) expect(gameGrid.length===STAGE2.level.length,true,"Height of stage is equal") expect(gameGrid[0].length===STAGE2.level[0].length,true,"Width of stage is equal") }) .it("current stage set to Stage 2",()=>{ loadStage(STAGE2) expect(gameStage===STAGE2,true) }) .it("accept only blue bots for Stage 2.",()=>{ loadStage(STAGE2) expect(gameStage.accept("BBB"),true,"Expect true for BBB") expect(gameStage.accept("RB"),false,"Expect false for RB") expect(gameStage.accept("BRBR"),false,"Expect false for BRBR") expect(gameStage.accept("BBBBBBBBBBBB"),true,"Expect true for BBBBBBBBBBBB") }) .it("bot fails at the start.",()=>{ loadStage(STAGE2) runBot(true) expect(gameState===REVIEWING,true) }) .it("When TESTING state is on, the game should test the current level for cases expecting to pass, but fail and create 3 of them if possible.",()=>{ loadStage(STAGE2) expect(BOT_QUEUE.length===0,true,"Bot queue should be empty.") generateBotQueue() expect(BOT_QUEUE.length===0&&gameState!==TESTING,true,"Bot queue should not be modified while state is not TESTING") gameState=TESTING generateBotQueue() expect(BOT_QUEUE.length===3,true,"There should be 3 bots in queue for an unbuilt level, as there are cases that do not pass.") }) .it("A stage should have an Exit.",()=>{ loadStage(STAGE2) var hasAnExit=()=>{ for (var y=0;y{ loadStage(STAGE2) placeBot(3,2) runBot(true) expect(gameState===FINISH,true) }) .it("Run a TESTING state to see if an acceptable player-built level has no bots in queue.",()=>{ loadStage(STAGE2) gameGrid=[ [{},{...BELTRIGHT},{...BELTRIGHT},{...BELTDOWN},{},], [{...BELTRIGHT},{...BRANCHUP},{},{...BELTDOWN},{},], [{},{...BRANCHRIGHT},{},{...BELTRIGHT},{type:"EXIT"},], [{},{},{},{},{},], [{},{},{},{},{},], ] expect(BOT_QUEUE.length===0,true,"Bot queue should be empty.") gameState=TESTING generateBotQueue() //console.log(BOT_QUEUE) expect(BOT_QUEUE.length===0,true,"There should be 0 bots in queue for a good level, as all bots are supposed to pass.") }) .showResults() TestSuite = new describe("Color Hex Conversion") TestSuite .it("converts a color to hex",()=>{ expect(colorToHex(0,0,0),"#000000") expect(colorToHex(66, 135, 245),"#4287f5") expect(colorToHex(245, 66, 221),"#f542dd") expect(colorToHex(58, 79, 55),"#3a4f37") }).showResults() console.log("----------------------") console.log("ALL TESTS: "+totalTestsPassed+" passed, "+(totalTests-totalTestsPassed)+" failed, "+totalTests+" total") if (testsPass===undefined) { testsPass=true } resetGame(); } function runGame() { resetGame(); setupGame(); //loadLevel(LEVEL2,0,2) setInterval(()=>{ step() draw() },1000/60) console.log("Running") } var RUNTESTS = true; loadScript("image_data.js",gameLoader) function gameLoader() { if (RUNTESTS) { loadScript("game.js",runTests) initializeGame() function initializeGame() { if (testsPass) { runGame() } else { setTimeout(()=>{ initializeGame() },1000) } } } else { loadScript("game.js",runGame) } }