function tests() { test("App class constructors and methods", function(assert) { // The App class must be defined equal(typeof App === 'function', true, "The App class must be defined"); equal(/^\s*class\s+/.test(App.toString()), true, "App is a function but it is not defined using the class keyword") // The App class constructor should throw an error if its argument is undefined assert.throws(function() { new App(undefined) }, "The App class constructor should throw an error if its argument is undefined") // The App class constructor should throw an error if its argument is not a canvas assert.throws(function() { new App(""); }, "The App class constructor should throw an error if its argument is not an object") assert.throws(function() { new App(1); }, "The App class constructor should throw an error if its argument is a number") assert.throws(function() { new App([]); }, "The App class constructor should throw an error if its argument is an array") assert.throws(function() { new App(true); }, "The App class constructor should throw an error if its argument is a boolean") // The default Stroke Style should be accessible in a static way, and should be equal to "black" equal(App.defaultStrokeStyle === 'black', true, 'The default Stroke Style should be accessible in a static way, and should be equal to "black"') assert.throws(function() { new App({}); }, "The App class constructor should throw an error if its argument options object is not pointing to a canvas element under the 'canvas' property") const app = new App({canvas: 'test-canvas'}) equal(app.strokeStyle, "black", "Getter for strokeStyle is not defined") // The draw method must be defined equal(typeof app.draw === 'function', true, "The draw method must be defined") }); test("History and Stroke object literals fields and methods", function(assert) { // The Stroke class must be defined equal(typeof Stroke === 'function', true, "The Stroke class must be defined"); equal(/^\s*class\s+/.test(Stroke.toString()), true, "Stroke is a function but it is not defined using the class keyword") equal(function(){ try { const stroke = new Stroke('square') } catch (err) { return false } return true }(), true, "Stroke can be instantiated") const stroke = new Stroke('square'); const stroke1 = new Stroke('circle'); const stroke2 = new Stroke('triangle'); history.initializeNewPath() assert.throws(function() { history.push() }, "Must pass a Stroke instance when you push in the history") equal(function() { try { history.push(stroke); } catch (err) { return false; } return true; }(), true, "History push accepts Stroke instances as a parameter"); equal(history.pop()[0] === stroke, true, "Pop returns an array containing the pushed Stroke instance") history.initializeNewPath(); history.push(stroke); history.push(stroke1); history.push(stroke2); equal(history.pop().length, 3, "Pop returns an array containing the pushed Stroke instances") history.initializeNewPath(); equal(history.pop().length, 0, "Pop on an empty history should return an empty array") history.initializeNewPath(); //simulate mouse down history.push(stroke); //simulate mouse move history.push(stroke1); //simulate mouse move history.initializeNewPath(); //simulate mouse up and down again history.push(stroke2); //simulate mouse move equal(history.pop().length, 1, "Pop returns an array containing the most recent path (Expected path with 1 Stroke)") equal(history.pop().length, 2, "Pop returns an array containing the most recent path (Expected path with 2 Strokes)") }); }