Skip to content

Instantly share code, notes, and snippets.

@ob-ivan
Last active September 5, 2015 11:29
Show Gist options
  • Save ob-ivan/0be499d282ff5dc88543 to your computer and use it in GitHub Desktop.
Save ob-ivan/0be499d282ff5dc88543 to your computer and use it in GitHub Desktop.
unequal
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<style>
input {
width: 32px;
text-align: center;
}
</style>
<script type="text/javascript" src="unitest.js"></script>
<script type="text/javascript" src="unequal.js"></script>
<script>
var test = new TestCase({
setUp : function () {
this.signTable = new SignTable(2, [[Sign.GT], [Sign.LT]]);
},
testGreaterThanSuccess : function () {
this.assert(this.signTable.acceptsLine(0, [3, 1]), '3 must be greater than 1');
},
testGreaterThanFail : function () {
this.assert(! this.signTable.acceptsLine(0, [1, 3]), '1 must not be greater than 3');
},
testLessThanSuccess : function () {
this.assert(this.signTable.acceptsLine(1, [2, 4]), '2 must be less than 4');
},
testLessThanFail : function () {
this.assert(! this.signTable.acceptsLine(1, [4, 2]), '4 must not be less than 2');
},
});
test.run();
// var size = 4;
var size = 5;
var game = new Game(size);
game.start();
</script>
</body>
</html>
// Model //
var FieldState = (function () {
/**
* @param integer[size][size] table
**/
var FieldState = function (size, table) {
this._size = size;
this._table = table;
};
FieldState.prototype.getSize = function () {
return this._size;
};
FieldState.prototype.getLine = function (i) {
return this._table[i];
};
return FieldState;
})();
var Sign = {
GT : 0,
LT : 1
};
var SignTable = (function () {
/**
* @param integer size
* @param Sign[size][size-1] table
**/
var SignTable = function (size, table) {
this._size = size;
this._table = table;
};
/**
* Tell whether all unequations in row i hold on a line of integers.
*
* @param integer i
* @param integer[size] line
* @return boolean
**/
SignTable.prototype.acceptsLine = function (i, line) {
if (!(0 <= i && i < this._size)) {
throw new Error(['i must be from 0 to ', size - 1, ', ', i, ' given'].join(''));
}
for (var j = 0; j < this._size - 1; ++j) {
if (line[j] > 0 && line[j + 1] > 0) {
if (this._table[i][j] === Sign.GT && !(line[j] > line[j + 1])) {
return false;
}
if (this._table[i][j] === Sign.LT && !(line[j] < line[j + 1])) {
return false;
}
}
}
return true;
};
SignTable.prototype.acceptsState = function (state) {
if (! state instanceof State) {
return false;
}
if (state.getSize() !== this._size) {
return false;
}
for (var i = 0; i < this._size; ++i) {
if (! this.acceptsLine(i, state.getLine(i))) {
return false;
}
}
return true;
};
return SignTable;
})();
var TableState = (function () {
var TableState = function (fieldState, horizSignTable, vertSignTable) {
this._fieldState = fieldState;
this._horizSignTable = horizSignTable;
this._vertSignTable = vertSignTable;
};
return TableState;
})();
// Operations //
var DocumentElementFactory = (function () {
var DocumentElementFactory = function () {
};
DocumentElementFactory.prototype.createTable = function () {
return document.createElement('table');
};
DocumentElementFactory.prototype.createTableRow = function () {
return document.createElement('tr');
};
DocumentElementFactory.prototype.createTableCell = function () {
return document.createElement('td');
};
DocumentElementFactory.prototype.createField = function () {
return document.createElement('input');
};
DocumentElementFactory.prototype.createSign = function (options) {
var sign = document.createElement('select');
for (var i = 0; i < options.length; ++i) {
var option = document.createElement('option');
option.value = options[i];
option.innerHTML = options[i];
sign.appendChild(option);
}
return sign;
};
DocumentElementFactory.prototype.createFiller = function () {
return document.createTextNode('\u00a0');
}
return DocumentElementFactory;
})();
var TableInitializer = (function () {
var TableInitializer = function (size, elementFactory) {
this._size = size;
this._elementFactory = elementFactory;
};
TableInitializer.prototype._setElementId = function (element, name, i, j) {
element.id = [name, i, j].join('_');
element.dataset.i = i;
element.dataset.j = j;
return element;
};
TableInitializer.prototype._createFieldCell = function (i, j) {
var cell = this._elementFactory.createTableCell();
var field = this._setElementId(
this._elementFactory.createField(),
'field', i, j
);
cell.appendChild(field);
return cell;
};
TableInitializer.prototype._createHorizontalSignCell = function (i, j) {
var cell = this._elementFactory.createTableCell();
var sign = this._setElementId(
this._elementFactory.createSign(['', '<', '>']),
'hor', i, j
);
cell.appendChild(sign);
return cell;
};
TableInitializer.prototype._createVerticalSignCell = function (i, j) {
var cell = this._elementFactory.createTableCell();
var sign = this._setElementId(
this._elementFactory.createSign(['', '^', 'v']),
'vert', i, j
);
cell.appendChild(sign);
return cell;
};
TableInitializer.prototype._createEmptyCell = function (i, j) {
var cell = this._elementFactory.createTableCell();
var filler = this._elementFactory.createFiller();
cell.appendChild(filler);
return cell;
};
TableInitializer.prototype._createFieldRow = function (i) {
var row = this._elementFactory.createTableRow();
for (var j = 0; j < this._size; ++j) {
var cell = this._createFieldCell(i, j);
row.appendChild(cell);
if (j < this._size - 1) {
var cell = this._createHorizontalSignCell(i, j);
row.appendChild(cell);
}
}
return row;
};
TableInitializer.prototype._createSignRow = function (i) {
var row = this._elementFactory.createTableRow();
for (var j = 0; j < this._size; ++j) {
var cell = this._createVerticalSignCell(i, j);
row.appendChild(cell);
if (j < this._size - 1) {
var cell = this._createEmptyCell(i, j);
row.appendChild(cell);
}
}
return row;
};
TableInitializer.prototype.createTable = function () {
var table = this._elementFactory.createTable();
for (var i = 0; i < this._size; ++i) {
var cellRow = this._createFieldRow(i);
table.appendChild(cellRow);
if (i < this._size - 1) {
var signRow = this._createSignRow(i);
table.appendChild(signRow);
}
}
return table;
};
return TableInitializer;
})();
// Application //
var Game = (function () {
var Game = function (size) {
this._size = size;
this._tableInitializer = new TableInitializer(size, new DocumentElementFactory());
};
Game.prototype.start = function () {
var table = this._tableInitializer.createTable();
document.body.appendChild(table);
};
return Game;
})();
var TestCase = (function () {
var TestCase = function (methods) {
this._methods = methods;
this._assertCount = 0;
this._successCount = 0;
this._failCount = 0;
this._testRx = /^test\w/;
};
TestCase.prototype._log = function (message) {
console.log(message);
};
TestCase.prototype._printResult = function () {
var summaryParts = ['Assertions: ', this._assertCount];
if (this._failCount > 0) {
this._log('--- FAILURE ---');
summaryParts = summaryParts.concat([' Fails: ', this._failCount]);
} else {
this._log('+++ SUCCESS +++');
}
this._log(summaryParts.join(''));
};
TestCase.prototype.success = function () {
++this._assertCount;
++this._successCount;
};
TestCase.prototype.fail = function (message) {
++this._assertCount;
++this._failCount;
this._log(message);
};
TestCase.prototype.assert = function (expression, message) {
if (expression) {
this.success();
} else {
this.fail(message);
}
};
TestCase.prototype.run = function () {
if (typeof this._methods.setUp !== 'undefined') {
this._methods.setUp.apply(this);
}
for (var methodName in this._methods) {
if (this._testRx.test(methodName)) {
try {
this._methods[methodName].apply(this);
} catch (e) {
this.fail('An error occured: ' + e);
}
}
}
if (typeof this._methods.tearDown !== 'undefined') {
this._methods.tearDown.apply(this);
}
this._printResult();
};
return TestCase;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment