2019-10-04 in class
This commit is contained in:
parent
6388526c01
commit
c72515f5ae
13 changed files with 28388 additions and 0 deletions
42
hw3/Claudio_Maggioni/index.html
Normal file
42
hw3/Claudio_Maggioni/index.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
<!-- DON'T MODIFY THIS FILE -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OO-JS Exercise - Web Atelier 2017</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
|
||||
<body onload="init()">
|
||||
<h1>
|
||||
OO-JS Exercise: Canvas
|
||||
</h1>
|
||||
<!-- <div id="clock">
|
||||
<div id="progress-bar"></div>
|
||||
<div id="clock-time"></div>
|
||||
</div> -->
|
||||
<div id="app">
|
||||
<div id="left-toolbar" class="toolbar">
|
||||
<button id="clear-btn">Clear</button>
|
||||
<button id="undo-btn">Undo</button>
|
||||
<button id="camera-btn"><i class="fa fa-camera" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
<canvas id="canvas" width="600" height="400"></canvas>
|
||||
<div id="brush-toolbar" class="toolbar">
|
||||
<!-- Brushes buttons go here (programmatically). Each button should be a <button> element -->
|
||||
</div>
|
||||
</div>
|
||||
<h2>Favourites</h2>
|
||||
<div id="favourites">
|
||||
<!-- Favourites will go here (programmatically). Each favourite should be an <img> element -->
|
||||
</div>
|
||||
<script src="scripts/brushes.js"></script>
|
||||
<script src="scripts/undo.js"></script>
|
||||
<!-- <script src="scripts/clock.js"></script> -->
|
||||
<script src="scripts/app.js"></script>
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
15
hw3/Claudio_Maggioni/main.js
Normal file
15
hw3/Claudio_Maggioni/main.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
// vim: set ts=2 sw=2 tw=80 et:
|
||||
// Enter your initialization code here
|
||||
|
||||
function init() {
|
||||
// Create canvas app
|
||||
const app = new App({
|
||||
canvas: 'canvas',
|
||||
buttons: {
|
||||
clear: 'clear-btn',
|
||||
camera: 'camera-btn',
|
||||
undo: 'undo-btn'
|
||||
},
|
||||
brushToolbar: 'brush-toolbar'
|
||||
});
|
||||
}
|
5
hw3/Claudio_Maggioni/qunit-compat.js
Normal file
5
hw3/Claudio_Maggioni/qunit-compat.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
let test = QUnit.test;
|
||||
let equal = QUnit.assert.equal.bind(QUnit.assert);
|
||||
let notEqual = QUnit.assert.notEqual.bind(QUnit.assert);
|
||||
let deepEqual = QUnit.assert.deepEqual.bind(QUnit.assert);
|
||||
let notDeepEqual = QUnit.assert.notDeepEqual.bind(QUnit.assert);
|
5588
hw3/Claudio_Maggioni/resources/jsverify.standalone.js
Normal file
5588
hw3/Claudio_Maggioni/resources/jsverify.standalone.js
Normal file
File diff suppressed because it is too large
Load diff
17084
hw3/Claudio_Maggioni/resources/lodash.js
Normal file
17084
hw3/Claudio_Maggioni/resources/lodash.js
Normal file
File diff suppressed because it is too large
Load diff
5048
hw3/Claudio_Maggioni/resources/qunit-2.4.0.js
Normal file
5048
hw3/Claudio_Maggioni/resources/qunit-2.4.0.js
Normal file
File diff suppressed because it is too large
Load diff
235
hw3/Claudio_Maggioni/resources/qunit.css
Normal file
235
hw3/Claudio_Maggioni/resources/qunit.css
Normal file
|
@ -0,0 +1,235 @@
|
|||
/**
|
||||
* QUnit v1.10.0 - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://qunitjs.com
|
||||
*
|
||||
* Copyright 2012 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699a4;
|
||||
background-color: #0d3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
-moz-border-radius: 5px 5px 0 0;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #c2ccd1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar label {
|
||||
display: inline-block;
|
||||
padding: 0 .5em 0 .1em;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2b81af;
|
||||
color: #fff;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #fff;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #c2ccd1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #e0f2be;
|
||||
color: #374e0c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #ffcaca;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: black; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
padding: 5px;
|
||||
background-color: #fff;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #3c510c;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #fff;
|
||||
border-left: 10px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 5px 5px;
|
||||
-moz-border-radius: 0 0 5px 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: green; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2b81af;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
#qunit-testresult .module-name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
83
hw3/Claudio_Maggioni/scripts/app.js
Normal file
83
hw3/Claudio_Maggioni/scripts/app.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
// vim: set ts=2 sw=2 et tw=80:
|
||||
class App {
|
||||
constructor(conf) {
|
||||
if (!(typeof conf === 'object' && conf)) {
|
||||
throw new Error('Argument conf different from specification');
|
||||
}
|
||||
|
||||
this.canvas = document.getElementById(conf.canvas);
|
||||
if (!this.canvas || this.canvas.tagName !== 'CANVAS') {
|
||||
throw new Error(`canvas is not a canvas`);
|
||||
}
|
||||
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.favourites = document.querySelector('div#favourites');
|
||||
|
||||
if (typeof conf.buttons === 'object' && conf.buttons) {
|
||||
this.buttons = {}
|
||||
for (const b of ['clear', 'button', 'camera'])
|
||||
this.buttons[b] = document.getElementById(conf.buttons[b]);
|
||||
|
||||
if (this.buttons.clear)
|
||||
this.buttons.clear.addEventListener('click', () =>
|
||||
this.ctx.clearRect(0, 0, canvas.width, canvas.height));
|
||||
|
||||
if (this.buttons.camera)
|
||||
this.buttons.camera.addEventListener('click', () => {
|
||||
const base64 = this.canvas.toDataURL();
|
||||
const img = document.createElement('img');
|
||||
img.src = base64;
|
||||
const span = document.createElement('span');
|
||||
span.contentEditable = true;
|
||||
this.favourites.appendChild(img);
|
||||
this.favourites.appendChild(span);
|
||||
});
|
||||
}
|
||||
|
||||
this.canvas.addEventListener('mousedown', (e) => {
|
||||
this.ctx.save();
|
||||
this.ctx.lineWidth = 1;
|
||||
this.ctx.moveTo(e.offsetX, e.offsetY);
|
||||
this.ctx.beginPath();
|
||||
this.mousedown = true;
|
||||
});
|
||||
|
||||
this.canvas.addEventListener('mousemove', (e) => this.mousedown && this.draw(e));
|
||||
|
||||
const endPath = (e) => {
|
||||
this.ctx.lineTo(e.offsetX, e.offsetY);
|
||||
this.ctx.stroke();
|
||||
this.ctx.restore();
|
||||
this.mousedown = false;
|
||||
};
|
||||
|
||||
this.canvas.addEventListener('mouseup', endPath);
|
||||
this.canvas.addEventListener('mouseout', endPath);
|
||||
|
||||
this.strokeStyle = this.constructor.defaultStrokeStyle;
|
||||
}
|
||||
|
||||
static get defaultStrokeStyle() {
|
||||
return 'black';
|
||||
}
|
||||
|
||||
get strokeStyle() {
|
||||
return this.ctx.strokeStyle;
|
||||
}
|
||||
|
||||
set strokeStyle(style) {
|
||||
if (typeof style !== 'string') {
|
||||
throw new Error('style is not a string');
|
||||
}
|
||||
this.ctx.strokeStyle = style;
|
||||
}
|
||||
|
||||
draw(e) {
|
||||
console.log(e);
|
||||
this.ctx.lineTo(e.offsetX, e.offsetY);
|
||||
this.ctx.stroke();
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(e.offsetX, e.offsetY);
|
||||
}
|
||||
}
|
||||
|
19
hw3/Claudio_Maggioni/scripts/brushes.js
Normal file
19
hw3/Claudio_Maggioni/scripts/brushes.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
class PenBrush {
|
||||
|
||||
constructor() {
|
||||
this.opacity = 1;
|
||||
this.name = "PenBrush";
|
||||
}
|
||||
|
||||
draw(ctx, strokeStyle, x, y) {
|
||||
ctx.lineJoin = ctx.lineCap = 'round';
|
||||
ctx.strokeStyle = strokeStyle;
|
||||
ctx.lineTo(x, y);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO DiscBrush
|
||||
//TODO StarBrush
|
||||
|
4
hw3/Claudio_Maggioni/scripts/undo.js
Normal file
4
hw3/Claudio_Maggioni/scripts/undo.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
const history = {
|
||||
|
||||
}
|
||||
|
136
hw3/Claudio_Maggioni/style.css
Normal file
136
hw3/Claudio_Maggioni/style.css
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* DO NOT MODIFY */
|
||||
body{
|
||||
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
|
||||
}
|
||||
|
||||
#app{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#canvas{
|
||||
border: 1px solid #bbb;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
width: 56px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toolbar button {
|
||||
height: 25px;
|
||||
width: 52px;
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#brush-toolbar{
|
||||
width: 84px;
|
||||
}
|
||||
|
||||
#brush-toolbar button{
|
||||
height: 40px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#palette{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-around;
|
||||
width: 53px;
|
||||
height: 204px;
|
||||
background-color: buttonface;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toolbar #camera-btn{
|
||||
font-size: 1.5em;
|
||||
line-height: 1.5em;
|
||||
color: #444;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
height: 40px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.toolbar #camera-btn:hover{
|
||||
background: #70a0e8;
|
||||
}
|
||||
|
||||
.toolbar #camera-btn:active{
|
||||
background: #0e57c3;
|
||||
}
|
||||
|
||||
.p-color{
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.black {background-color:rgb(0, 0, 0);}
|
||||
.dark-gray {background-color:rgb(87, 87, 87);}
|
||||
.red {background-color:rgb(173, 35, 35);}
|
||||
.blue {background-color:rgb(42, 75, 215);}
|
||||
.green {background-color:rgb(29, 105, 20);}
|
||||
.brown {background-color:rgb(129, 74, 25);}
|
||||
.purple {background-color:rgb(129, 38, 192);}
|
||||
.light-gray {background-color:rgb(160, 160, 160);}
|
||||
.light-green {background-color:rgb(129, 197, 122);}
|
||||
.light-blue {background-color:rgb(157, 175, 255);}
|
||||
.cyan {background-color:rgb(41, 208, 208);}
|
||||
.orange {background-color:rgb(255, 146, 51);}
|
||||
.yellow {background-color:rgb(255, 238, 51);}
|
||||
.tan {background-color:rgb(233, 222, 187);}
|
||||
.pink {background-color:rgb(255, 205, 243);}
|
||||
.white {background-color:rgb(255, 255, 255);}
|
||||
|
||||
#clock {
|
||||
background-color: #ddd;
|
||||
width: 360px;
|
||||
height: 48px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
font-size: 2.5rem;
|
||||
margin-top: -10px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#clock-time,
|
||||
#progress-bar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
#clock-time {
|
||||
z-index: 10;
|
||||
line-height: 48px; /* same height as #clock so that the time is vertically centered */
|
||||
}
|
||||
|
||||
#progress-bar {
|
||||
width: 0%;
|
||||
height: 48px;
|
||||
background-color: #8DFF80;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#favourites div.gallery {
|
||||
margin: 5px;
|
||||
float: left;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#favourites div.gallery img {
|
||||
width: 90%;
|
||||
height: 100px;
|
||||
box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.42);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#favourites div.desc {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
}
|
26
hw3/Claudio_Maggioni/test.html
Normal file
26
hw3/Claudio_Maggioni/test.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Exercise 3 - Object-oriented Javascript</title>
|
||||
<link rel="stylesheet" href="resources/qunit.css">
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="test-canvas" width="600" height="400" style="display: none"></canvas>
|
||||
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
<script src="scripts/brushes.js"></script>
|
||||
<script src="scripts/undo.js"></script>
|
||||
<script src="scripts/clock.js"></script>
|
||||
<script src="scripts/app.js"></script>
|
||||
<script src="resources/qunit-2.4.0.js"></script>
|
||||
<script src="resources/lodash.js"></script>
|
||||
<script src="resources/jsverify.standalone.js"></script>
|
||||
<script src="qunit-compat.js"></script>
|
||||
<script src="test.js"></script>
|
||||
<script>
|
||||
tests();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
103
hw3/Claudio_Maggioni/test.js
Normal file
103
hw3/Claudio_Maggioni/test.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
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)")
|
||||
|
||||
});
|
||||
}
|
Reference in a new issue