Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Store printers on per cell basis (Closes #4)

  • Loading branch information...
commit cfdfce2cd2aedd2e2edc5bb87fdf9e299199bbf9 1 parent 3e97b97
@eldargab authored
Showing with 94 additions and 29 deletions.
  1. +81 −26 lib/table.js
  2. +13 −3 test/table.js
View
107 lib/table.js
@@ -1,67 +1,121 @@
module.exports = Table;
function Table () {
- this.shift = ' ';
this.columns = {};
this.lines = [];
- this.line = {};
+ this.line = new Line;
}
-Table.prototype.cell = function (col, obj, printer, length) {
- this.line[col] = obj;
+function Line () {
+ Object.defineProperties(this, {
+ __printers: {
+ value: {},
+ enumerable: false
+ },
+ __cell: {
+ value: function (col, val, printer) {
+ this[col] = val;
+ this.__printers[col] = printer;
+ },
+ enumerable: false
+ }
+ })
+}
- var c = this.columns[col] || (this.columns[col] = {length: col.length});
- c.printer = printer || Table.string;
- if (length != null) {
- c.length = length;
- }
- else {
- var s = c.printer(obj);
- c.length = s.length > c.length ? s.length : c.length;
- }
+Table.prototype.cell = function (col, val, printer, length) {
+ this.line.__cell(col, val, printer)
+ var c = this.columns[col] || (this.columns[col] = {
+ printer: printer || Table.string
+ });
+ c.length = length > c.length || c.length == null ? length : c.length
return this;
}
Table.prototype.newLine = function () {
this.lines.push(this.line);
- this.line = {};
+ this.line = new Line;
return this;
}
+Table.prototype.shift = ' ';
+
+Table.prototype.toString = function () {
+ return new Printer(this).print();
+}
+
Table.prototype.sort = require('./sort');
-Table.prototype.toString = function () {
- var self = this;
+function Printer (table) {
+ this.table = table
+ this.columns = table.columns
+ this.colLengths = {}
+ this.shift = table.shift
+}
+
+Printer.prototype.print = function () {
var padWithDashs = RightPadder('-');
var s = '';
-
- s += this._printLine(function (key) {
+
+ this.calcColumnLengths();
+
+ s += this.printLine(function (key) {
return key;
});
- s += this._printLine(function (key, col) {
- return padWithDashs('', col.length);
+ s += this.printLine(function (key, length) {
+ return padWithDashs('', length);
});
- this.lines.forEach(function (line) {
- s += self._printLine(function (key, col) {
- return col.printer(line[key], col.length);
+ this.forEachLine(function (line) {
+ s += this.printLine(function (key, length) {
+ return this.cellPrinter(line, key).call(line, line[key], length);
});
});
return s;
}
-Table.prototype._printLine = function (print) {
+Printer.prototype.forEachLine = function (cb) {
+ return this.table.lines.forEach(cb, this);
+}
+
+Printer.prototype.cellPrinter = function (line, col) {
+ return line.__printers[col] || this.columns[col].printer;
+}
+
+
+Printer.prototype.calcColumnLengths = function () {
+ var setLength = function (col, length) {
+ var isFixed = this.columns[col].length != null;
+ if (isFixed) {
+ this.colLengths[col] = this.columns[col].length
+ } else {
+ if (this.colLengths[col] > length) return
+ this.colLengths[col] = length
+ }
+ }.bind(this)
+
+ for (var key in this.columns) {
+ setLength(key, key.length)
+ }
+
+ this.forEachLine(function (line) {
+ for (var key in this.columns) {
+ setLength(key, this.cellPrinter(line, key).call(line, line[key]).length)
+ }
+ })
+}
+
+Printer.prototype.printLine = function (print) {
var s = '';
var firstColumn = true;
for (var key in this.columns) {
if (!firstColumn) s += this.shift;
firstColumn = false;
- var col = this.columns[key];
- s += printCell(print(key, col), col.length);
+ var l = this.colLengths[key]
+ s += printCell(print.call(this, key, l), l);
}
s += '\n';
return s;
@@ -101,6 +155,7 @@ function LeftPadder (char) {
}
}
+
Table.padLeft = LeftPadder();
Table.string = function (obj) {
View
16 test/table.js
@@ -47,7 +47,8 @@ describe('Easy table', function () {
callCount++;
return obj.toString();
}
- t.cell('col', 10, print);
+ t.cell('col', 10, print).newLine().toString();
+ callCount.should.be.equal(2)
});
it('Second time asking to render actual value passing additional length parameter', function () {
@@ -63,6 +64,15 @@ describe('Easy table', function () {
t.cell('col', 10, print).newLine();
expectLine(3).be.equal(' 10 ');
});
+
+ it('It should be called with `this` set to line', function () {
+ function print (obj) {
+ this.should.have.property('bar')
+ this.should.have.property('baz')
+ return obj.toString()
+ }
+ t.cell('bar', 1, print).cell('baz', 2, print).newLine().toString()
+ })
});
describe('Should accept column length as 4-th parameter to .cell() method. In such case:', function () {
@@ -71,7 +81,7 @@ describe('Easy table', function () {
expectLine(3).be.equal('value ');
});
- it('If cell value doesn`t fit column width it should be trancated', function () {
+ it('If cell value doesn`t fit it should be trancated', function () {
t.cell('col', 'A very long value', null, 14).newLine();
expectLine(3).be.equal('A very long...');
});
@@ -81,7 +91,7 @@ describe('Easy table', function () {
Table.padLeft('a', 2).should.equal(' a');
});
- it('test .sort() function', function () {
+ it('test .sort()', function () {
t.cell('a', 1).newLine();
t.cell('a', 2).newLine();
t.cell('a', null).newLine();
Please sign in to comment.
Something went wrong with that request. Please try again.