test-table
v3.0.3
Published
a simple table for data-driven testing
Downloads
168
Readme
test-table
A very simple table for data-driven testing. test-table is provided through quicbit-js/test-kit, but can be used independently as well.
Complies with the 100% test coverage and minimum dependency requirements of qb-standard .
Install
npm install test-table
Usage
You can create a table from an array of array values where the first row has the column names:
> var table = require('test-table').create;
> var tbl = table([
['col-a', 'col-b', 'col-c'],
[1, 2, 3],
['x', 'y', 'z']
]);
Access header and rows properties:
> console.log(tbl.header)
[ 'col-a', 'col-b', 'col-c' ]
> console.log(tbl.rows[0])
{ col-a: 1, col-b: 2, col-c: 3 }
Using test-table together with a simple framework like tape condenses test cases and create more coverage. Let's say we want to test a utility function count(s, v) function which returns the number of occurences of substring v within string s:
var test = require('tape');
var util = require('myutil'); // has the util.count(s, v) function to test
test('test-defaults: count', function(t) {
let tbl = t.table([
[ 's', 'v', 'expect' ],
[ '', '10', 0 ],
[ '10', '10', 1 ],
[ '101', '10', 1 ],
[ '1010', '10', 2 ],
[ '0100101001', '0', 6 ],
[ '0100101001', '1', 4 ],
[ '0100101001', '10', 3 ],
[ '0100101001', '100', 2 ],
[ '0100101001', '1000', 0 ],
]);
t.plan(tbl.length);
tbl.forEach(function(r) {
t.equal(util.count(r.s, r.v), r.expect);
})
})
Check out test-kit for more ways to
make testing even more concise:
var test = require('test-kit)(require('tape')) // an enriched test harness
test('test-defaults: count', function(t) {
t.tableAssert([
[ 's', 'v', 'expect' ],
[ '', '10', 0 ],
[ '10', '10', 1 ],
[ '101', '10', 1 ],
[ '1010', '10', 2 ],
[ '0100101001', '0', 6 ],
[ '0100101001', '1', 4 ],
[ '0100101001', '10', 3 ],
[ '0100101001', '100', 2 ],
[ '0100101001', '1000', 0 ],
], require('myutil').count);
})
API
create (data, opt)
Create table from a matrix (array of arrays of data). If data is already a table, then simply return it (similar to new Object(someObject)).
For arrays, the first array is assumed to be the header, unless opt.header is set, in which case that will be used for the header. opt.header may be an array of strings or a string containing '%d'. If a header is a string, the header strings will be generated by replacing %d with the column offset. IOW, these statements will all create the same table and header:
var tbl = table.create( [ [1, 2], [3, 4] ], { header: ['c_0','c_1'] } ) // 'c_' is the default header prefix
var tbl = table.create( [ [1, 2], [3, 4] ], { header: 'c_%d' } ) // using a header pattern
var tbl = table.create( [ ['c_0','c_1'], [1, 2], [3, 4] ] ) // explicit headers
var tbl = table.create( [ 'c_%d', [1, 2], [3, 4] ] ) // putting the header pattern with the data
tracking comments
As of version 2.4.2, test-table supports comments maintained internally as a separate structure. Comments are simply strings that begin with the hash '#' character.
node
> var t1 = table.create([
'#head',
['a','b','c'],
[ 1, 2, 3 ],
'#r2',
[ 4, 5, 6 ],
'#trail'
])
> console.log(t1.toString())
#head
a,b,c
1,2,3
#r2
4,5,6
#trail
> console.log(t1.toString({with_comments: false}))
a,b,c
1,2,3
4,5,6
The tree comments provided in the above example have slightly different features. The comments above the header and below the last row are table-level comments. They are carried over to the any new table when performing row selection via the trows() or tcols() functions. The '#r2' comment above the bottom row is kept with the row below and is removed if that row is removed.
as_arrays (opt)
Return the table, including the header, as an array of arrays. opt.with_comments will cause comment strings to be included in the returned array.
col_name (idx_or_name)
Return the name (string) for the given column number. If col_name is already a string, then that string is returned.
col_index (name)
return the column index for the given column name.
tcols (beg, end)
return a new table in the given column range using the same range selection as Array.prototype.slice (which allows negative args as offsets from end)
trows (beg, end)
return a new table in the given row range using the same range selection as Array.prototype.slice (which allows negative args as offsets from end)
data ()
Return all the data in the table as a matrix (array of arrays). The header is not returned.
val (row, col)
Return the value at the given row (number) and column (number or string). If only row arg is given, return the entire row.
set_val (row, col, v)
Set cell for the given row (integer) and column (name or integer) to v.
vals (col)
Return all the values in the given row (name or integer) as an array.
unequal_cell (tbl, opt)
Compare a table with another table row-by-row (tbl) and return a [row, column] tuple indicating the first cell (i.e. the lowest number row and column) that is different.
opt
max_depth - integer. nested object/array depth at which depth false will be returned for object
or array values that are not strictly equal.
equal - function (a, b, depth, maxdepth), allows you to provide a custom function for comparing
nested data (objects/arrays) The comparison can take depth into account.
The default comparison recursively
compares object and array contents by type and then by strict '===' comparison,
returning *false* if max_depth is met. However, returns true for two isNaN numbers.
Deprecated Functions
col (name) : use "vals(idx_or_name)" instead
slice (beg, end) : use "tcols(beg, end)" instead
Table Comparison
Comparing tables and/or showing first difference can be helpful in testing. test-table has a couple functions for this:
unequal_cell() returns the [row, col] location of the first differing cell value found between two given tables:
table1.unequal_cell(table2, options) '
... where options can provide
{
equal: function (a, b, depth, max_depth) // custom equal function (which may or may not honor depth argument)
max_depth // max_depth passed to equal function
}
by default, equals will perform deep compare of arrays and plain objects (but not other types like dates).
equals() checks that headers and row values are the same using the same comparisons as unequal_cell (returning true iff all cells are equal)
Header Generation
If you find yourself with a wide matrix of data and no header, test-table can generate the header for you using a template string:
var table = require('test-table').create
var tbl = table(
[
[ 0.3, 3.2, 2.7, 2.5, 1.3, 4.2, 2.0 ],
[ 0.4, 3.1, 8.1, 2.5, 1.0, 5.2, 2.0 ],
[ 0.4, 3.3, 2.2, 2.5, 1.0, 4.6, 2.0 ],
[ 0.3, 3.0, 2.9, 2.5, 1.3, 5.2, 2.0 ],
[ 0.3, 3.2, 4.3, 2.5, 1.0, 5.2, 2.0 ],
[ 0.5, 4.2, 6.2, 2.5, 1.3, 4.6, 2.0 ],
],
{ header: 'col_%d' }
);
The '%d' in the template will be replaced with the column number to generate headers:
> console.log(tbl.header);
[ 'col_0', 'col_1', 'col_2', 'col_3', 'col_4', 'col_5', 'col_6' ]
A header template can also be used in lue of a header array:
var tbl = table(
[
'col_%d',
[ 0.3, 3.2, 2.7, 2.5, 1.3, 4.2, 2.0 ],
[ 0.4, 3.1, 8.1, 2.5, 1.0, 5.2, 2.0 ],
[ 0.4, 3.3, 2.2, 2.5, 1.0, 4.6, 2.0 ],
[ 0.3, 3.0, 2.9, 2.5, 1.3, 5.2, 2.0 ],
[ 0.3, 3.2, 4.3, 2.5, 1.0, 5.2, 2.0 ],
[ 0.5, 4.2, 6.2, 2.5, 1.3, 4.6, 2.0 ],
]
);