logtunnel 0.4.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +259 -0
- package/package.json +2 -2
- package/src/definition.js +33 -30
- package/src/log-source.js +1 -1
- package/src/main.js +3 -1
- package/src/pipeline.js +55 -21
- package/src/transformers/filters/field.js +18 -0
- package/src/transformers/filters/find.js +11 -0
- package/src/transformers/filters/ignore.js +11 -0
- package/src/transformers/outputs/bigodon.js +17 -0
- package/src/transformers/outputs/factory.js +21 -0
- package/src/transformers/outputs/inspect.js +22 -0
- package/src/transformers/outputs/json.js +11 -0
- package/src/transformers/outputs/logfmt.js +13 -0
- package/src/transformers/outputs/original.js +7 -0
- package/src/transformers/outputs/table.js +67 -0
- package/src/transformers/parsers/factory.js +16 -0
- package/src/transformers/parsers/json.js +16 -0
- package/src/transformers/parsers/logfmt.js +13 -0
- package/src/transformers/parsers/regex.js +11 -0
- package/src/transformers/parsers/table.js +31 -0
- package/test/filters.spec.js +40 -40
- package/test/output.spec.js +61 -22
- package/test/parse.spec.js +20 -22
- package/test/pipeline.spec.js +107 -21
- package/test/utils.js +8 -2
- package/src/transformers/field.js +0 -11
- package/src/transformers/filter.js +0 -4
- package/src/transformers/ignore.js +0 -4
- package/src/transformers/output-json.js +0 -7
- package/src/transformers/output-logfmt.js +0 -9
- package/src/transformers/output-mustache.js +0 -13
- package/src/transformers/output-original.js +0 -3
- package/src/transformers/output-unset.js +0 -12
- package/src/transformers/output.js +0 -15
- package/src/transformers/parse-json.js +0 -12
- package/src/transformers/parse-logfmt.js +0 -9
- package/src/transformers/parse-regex.js +0 -4
- package/src/transformers/parse-table.js +0 -26
- package/src/transformers/parse.js +0 -14
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class TableOutput {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.rows = [];
|
|
4
|
+
this.columns = [];
|
|
5
|
+
this.columnWidths = new Map();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
run(line) {
|
|
9
|
+
if (typeof line !== 'object') {
|
|
10
|
+
throw new Error("To use an output transformer, you need to specify a parser like '-p json'");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.rows.push(line);
|
|
14
|
+
|
|
15
|
+
Object.keys(line).forEach(column => {
|
|
16
|
+
if (!this.columnWidths.has(column)) {
|
|
17
|
+
this.columns.push(column);
|
|
18
|
+
this.columnWidths.set(column, column.length);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const cell = this._toCell(line[column]);
|
|
22
|
+
const width = this.columnWidths.get(column);
|
|
23
|
+
if (cell.length > width) {
|
|
24
|
+
this.columnWidths.set(column, cell.length);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
flush() {
|
|
31
|
+
if (this.rows.length === 0) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const columns = this.columns;
|
|
36
|
+
const widths = columns.map(column => this.columnWidths.get(column));
|
|
37
|
+
|
|
38
|
+
const lines = [];
|
|
39
|
+
lines.push(this._formatRow(columns, widths));
|
|
40
|
+
this.rows.forEach(row => {
|
|
41
|
+
const cells = columns.map(column => this._toCell(row[column]));
|
|
42
|
+
lines.push(this._formatRow(cells, widths));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return lines;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_toCell(value) {
|
|
49
|
+
if (value === null || value === undefined) {
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
if (typeof value === 'object') {
|
|
53
|
+
return JSON.stringify(value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return String(value);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_formatRow(cells, widths) {
|
|
60
|
+
return cells
|
|
61
|
+
.map((cell, index) => cell.padEnd(widths[index]))
|
|
62
|
+
.join(' ')
|
|
63
|
+
.trimEnd();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = { TableOutput };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { JsonParse } = require("./json");
|
|
2
|
+
const { LogfmtParse } = require("./logfmt");
|
|
3
|
+
const { TableParse } = require("./table");
|
|
4
|
+
const { RegexParse } = require("./regex");
|
|
5
|
+
|
|
6
|
+
function parseFactory(format) {
|
|
7
|
+
switch(format?.toLowerCase()) {
|
|
8
|
+
case void 0: return null;
|
|
9
|
+
case 'json': return new JsonParse();
|
|
10
|
+
case 'logfmt': return new LogfmtParse();
|
|
11
|
+
case 'table': return new TableParse();
|
|
12
|
+
default: return new RegexParse(format);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = { parseFactory };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class TableParse {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.headers = null;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
run(line, _original, firstLine) {
|
|
7
|
+
if (!firstLine) {
|
|
8
|
+
// Ignore first line, it's the headers
|
|
9
|
+
this.headers = this._splitColumns(line);
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (!this.headers) {
|
|
13
|
+
this.headers = this._splitColumns(firstLine);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const columns = this._splitColumns(line);
|
|
17
|
+
const obj = {};
|
|
18
|
+
|
|
19
|
+
this.headers.forEach((header, i) => {
|
|
20
|
+
obj[header] = columns[i];
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return obj;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_splitColumns(line) {
|
|
27
|
+
return line.replace(/\s+/g, ' ').split(' ');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { TableParse };
|
package/test/filters.spec.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const Lab = require('@hapi/lab');
|
|
2
2
|
const Code = require('@hapi/code');
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
4
|
+
const { FindFilter } = require('../src/transformers/filters/find');
|
|
5
|
+
const { IgnoreFilter } = require('../src/transformers/filters/ignore');
|
|
6
|
+
const { FieldFilter } = require('../src/transformers/filters/field');
|
|
7
7
|
|
|
8
8
|
const { describe, it } = exports.lab = Lab.script();
|
|
9
9
|
const { expect } = Code;
|
|
@@ -11,76 +11,76 @@ const { expect } = Code;
|
|
|
11
11
|
describe('filters', () => {
|
|
12
12
|
describe('--filter', () => {
|
|
13
13
|
it('should accept matching strings', () => {
|
|
14
|
-
const transformer =
|
|
15
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
14
|
+
const transformer = new FindFilter('psu');
|
|
15
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
16
16
|
expect(result).to.be.true();
|
|
17
17
|
});
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
it('should reject non-matching strings', () => {
|
|
20
|
-
const transformer =
|
|
21
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
20
|
+
const transformer = new FindFilter('aaa');
|
|
21
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
22
22
|
expect(result).to.be.false();
|
|
23
23
|
});
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
it('should be case insensitive', () => {
|
|
26
|
-
const transformer =
|
|
27
|
-
const result = transformer('lorem ipSUm dolor sit amet');
|
|
26
|
+
const transformer = new FindFilter('PsU');
|
|
27
|
+
const result = transformer.run('lorem ipSUm dolor sit amet');
|
|
28
28
|
expect(result).to.be.true();
|
|
29
29
|
});
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
it('should support regex', () => {
|
|
32
|
-
const transformer =
|
|
33
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
32
|
+
const transformer = new FindFilter('i.*m');
|
|
33
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
34
34
|
expect(result).to.be.true();
|
|
35
35
|
});
|
|
36
36
|
});
|
|
37
37
|
describe('--ignore', () => {
|
|
38
38
|
it('should reject matching strings', () => {
|
|
39
|
-
const transformer =
|
|
40
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
39
|
+
const transformer = new IgnoreFilter('psu');
|
|
40
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
41
41
|
expect(result).to.be.false();
|
|
42
42
|
});
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
it('should accept non-matching strings', () => {
|
|
45
|
-
const transformer =
|
|
46
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
45
|
+
const transformer = new IgnoreFilter('aaa');
|
|
46
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
47
47
|
expect(result).to.be.true();
|
|
48
48
|
});
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
it('should be case insensitive', () => {
|
|
51
|
-
const transformer =
|
|
52
|
-
const result = transformer('lorem ipSUm dolor sit amet');
|
|
51
|
+
const transformer = new IgnoreFilter('PsU');
|
|
52
|
+
const result = transformer.run('lorem ipSUm dolor sit amet');
|
|
53
53
|
expect(result).to.be.false();
|
|
54
54
|
});
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
it('should support regex', () => {
|
|
57
|
-
const transformer =
|
|
58
|
-
const result = transformer('lorem ipsum dolor sit amet');
|
|
57
|
+
const transformer = new IgnoreFilter('i.*m');
|
|
58
|
+
const result = transformer.run('lorem ipsum dolor sit amet');
|
|
59
59
|
expect(result).to.be.false();
|
|
60
60
|
});
|
|
61
61
|
});
|
|
62
62
|
describe('--field', () => {
|
|
63
|
-
it('should error when strings wasn\'t parsed into object', () => {
|
|
64
|
-
const transformer =
|
|
65
|
-
expect(
|
|
63
|
+
it('should error when strings wasn\'t parsed into object', async () => {
|
|
64
|
+
const transformer = new FieldFilter('a');
|
|
65
|
+
expect(transformer.run('a')).to.reject();
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
it('should compare equality', () => {
|
|
69
|
-
const transformer =
|
|
70
|
-
expect(transformer({ foo: 'bar' })).to.be.true();
|
|
71
|
-
expect(transformer({ foo: 'baz' })).to.be.false();
|
|
68
|
+
it('should compare equality', async () => {
|
|
69
|
+
const transformer = new FieldFilter('eq foo "bar"');
|
|
70
|
+
expect(await transformer.run({ foo: 'bar' })).to.be.true();
|
|
71
|
+
expect(await transformer.run({ foo: 'baz' })).to.be.false();
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
it('should compare inequality with strings', () => {
|
|
75
|
-
const transformer =
|
|
76
|
-
expect(transformer({ foo: '3' })).to.be.true();
|
|
77
|
-
expect(transformer({ foo: '2' })).to.be.false();
|
|
74
|
+
it('should compare inequality with strings', async () => {
|
|
75
|
+
const transformer = new FieldFilter('gte foo 3');
|
|
76
|
+
expect(await transformer.run({ foo: '3' })).to.be.true();
|
|
77
|
+
expect(await transformer.run({ foo: '2' })).to.be.false();
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
-
it('should accept javascript', () => {
|
|
81
|
-
const transformer =
|
|
82
|
-
expect(transformer({ foo: 'ABARA' })).to.be.true();
|
|
83
|
-
expect(transformer({ foo: 'ABADA' })).to.be.false();
|
|
80
|
+
it('should accept javascript', async () => {
|
|
81
|
+
const transformer = new FieldFilter('includes (lower foo) "bar"');
|
|
82
|
+
expect(await transformer.run({ foo: 'ABARA' })).to.be.true();
|
|
83
|
+
expect(await transformer.run({ foo: 'ABADA' })).to.be.false();
|
|
84
84
|
});
|
|
85
85
|
});
|
|
86
86
|
});
|
package/test/output.spec.js
CHANGED
|
@@ -1,57 +1,96 @@
|
|
|
1
1
|
const Lab = require('@hapi/lab');
|
|
2
2
|
const Code = require('@hapi/code');
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const { outputFactory } = require('../src/transformers/outputs/factory');
|
|
5
5
|
|
|
6
6
|
const { describe, it } = exports.lab = Lab.script();
|
|
7
7
|
const { expect } = Code;
|
|
8
8
|
|
|
9
9
|
describe('outputs', () => {
|
|
10
10
|
it('should should not modify unparsed when unset', () => {
|
|
11
|
-
const format =
|
|
12
|
-
expect(format('foo')).to.be.true();
|
|
11
|
+
const format = outputFactory();
|
|
12
|
+
expect(format.run('foo')).to.be.true();
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
it('should
|
|
16
|
-
const format =
|
|
17
|
-
const line = format({ foo: 'bar' });
|
|
15
|
+
it('should inspect parsed lines single-line when unset', () => {
|
|
16
|
+
const format = outputFactory();
|
|
17
|
+
const line = format.run({ foo: 'bar' });
|
|
18
18
|
expect(line).to.be.a.string();
|
|
19
19
|
expect(line).to.match(/\{.*foo.*:.*bar.*\}/);
|
|
20
|
+
expect(line.split('\n').length).to.equal(1);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should inspect parsed lines multi-line', () => {
|
|
24
|
+
const format = outputFactory('inspect');
|
|
25
|
+
const line = format.run({ foo: 'bar' });
|
|
26
|
+
expect(line).to.be.a.string();
|
|
27
|
+
expect(line.split('\n').join(' ')).to.match(/\{.*foo.*:.*bar.*\}/);
|
|
28
|
+
expect(line.split('\n').length).to.equal(3);
|
|
20
29
|
});
|
|
21
30
|
|
|
22
31
|
it('should format as json', () => {
|
|
23
|
-
const format =
|
|
24
|
-
const line = format({ foo: 'bar' });
|
|
32
|
+
const format = outputFactory('json');
|
|
33
|
+
const line = format.run({ foo: 'bar' });
|
|
25
34
|
expect(line).to.equal('{"foo":"bar"}');
|
|
26
35
|
});
|
|
27
36
|
|
|
28
37
|
it('should format as logfmt', () => {
|
|
29
|
-
const format =
|
|
30
|
-
const line = format({ foo: 'bar' });
|
|
38
|
+
const format = outputFactory('logfmt');
|
|
39
|
+
const line = format.run({ foo: 'bar' });
|
|
31
40
|
expect(line).to.equal('foo=bar');
|
|
32
41
|
});
|
|
33
42
|
|
|
34
43
|
it('should format as original', () => {
|
|
35
|
-
const format =
|
|
36
|
-
const line = format({ foo: 'bar' }, 'fubá');
|
|
44
|
+
const format = outputFactory('original');
|
|
45
|
+
const line = format.run({ foo: 'bar' }, 'fubá');
|
|
37
46
|
expect(line).to.equal('fubá');
|
|
38
47
|
});
|
|
39
48
|
|
|
40
|
-
it('should format
|
|
41
|
-
const format =
|
|
42
|
-
|
|
49
|
+
it('should format as table', () => {
|
|
50
|
+
const format = outputFactory('table');
|
|
51
|
+
format.run({ foo: 'bar', baz: 'qux' });
|
|
52
|
+
format.run({ foo: 'longer' });
|
|
53
|
+
const lines = format.flush();
|
|
54
|
+
|
|
55
|
+
expect(lines).to.equal([
|
|
56
|
+
'foo baz',
|
|
57
|
+
'bar qux',
|
|
58
|
+
'longer',
|
|
59
|
+
]);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should return empty table output when no rows were provided', () => {
|
|
63
|
+
const format = outputFactory('table');
|
|
64
|
+
expect(format.flush()).to.equal([]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should stringify object and null table cells', () => {
|
|
68
|
+
const format = outputFactory('table');
|
|
69
|
+
format.run({ foo: null, bar: { baz: 1 } });
|
|
70
|
+
const lines = format.flush();
|
|
71
|
+
|
|
72
|
+
expect(lines).to.equal([
|
|
73
|
+
'foo bar',
|
|
74
|
+
' {"baz":1}',
|
|
75
|
+
]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should format with bigodon', async () => {
|
|
79
|
+
const format = outputFactory('[{{foo}}]');
|
|
80
|
+
const line = await format.run({ foo: 'bar' });
|
|
43
81
|
expect(line).to.equal('[bar]');
|
|
44
82
|
});
|
|
45
83
|
|
|
46
|
-
it('should allow
|
|
47
|
-
const format =
|
|
48
|
-
const line = format({ foo: 'bar' });
|
|
84
|
+
it('should allow bigodon helpers', async () => {
|
|
85
|
+
const format = outputFactory('[{{upper foo }}]');
|
|
86
|
+
const line = await format.run({ foo: 'bar' });
|
|
49
87
|
expect(line).to.equal('[BAR]');
|
|
50
88
|
});
|
|
51
89
|
|
|
52
|
-
it('should refuse to format unparsed lines', () => {
|
|
53
|
-
expect(() =>
|
|
54
|
-
expect(() =>
|
|
55
|
-
expect(() =>
|
|
90
|
+
it('should refuse to format unparsed lines', async () => {
|
|
91
|
+
expect(() => outputFactory('json').run('foo')).to.throw();
|
|
92
|
+
expect(() => outputFactory('logfmt').run('foo')).to.throw();
|
|
93
|
+
expect(() => outputFactory('table').run('foo')).to.throw();
|
|
94
|
+
await expect(outputFactory('{{foo}}').run('foo')).to.reject();
|
|
56
95
|
});
|
|
57
96
|
});
|
package/test/parse.spec.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
const Lab = require('@hapi/lab');
|
|
2
2
|
const Code = require('@hapi/code');
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const { parseFactory } = require('../src/transformers/parsers/factory');
|
|
5
5
|
|
|
6
6
|
const { describe, it } = exports.lab = Lab.script();
|
|
7
7
|
const { expect } = Code;
|
|
8
8
|
|
|
9
9
|
describe('parsers', () => {
|
|
10
10
|
it('should return null when no format is specified', () => {
|
|
11
|
-
expect(
|
|
11
|
+
expect(parseFactory(void 0)).to.be.null();
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
it('should parse json', () => {
|
|
15
|
-
const parser =
|
|
16
|
-
expect(parser('{"foo": "bar"}')).to.equal({ foo: 'bar' });
|
|
15
|
+
const parser = parseFactory('json');
|
|
16
|
+
expect(parser.run('{"foo": "bar"}')).to.equal({ foo: 'bar' });
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
it('should ignore invalid json lines when parsing json', () => {
|
|
20
|
-
const parser =
|
|
21
|
-
expect(parser('Oy')).to.be.false();
|
|
22
|
-
expect(parser('"Oy"')).to.be.false();
|
|
20
|
+
const parser = parseFactory('json');
|
|
21
|
+
expect(parser.run('Oy')).to.be.false();
|
|
22
|
+
expect(parser.run('"Oy"')).to.be.false();
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('should parse logfmt', () => {
|
|
26
|
-
const parser =
|
|
27
|
-
expect(parser('foo=bar')).to.equal({ foo: 'bar' });
|
|
26
|
+
const parser = parseFactory('logfmt');
|
|
27
|
+
expect(parser.run('foo=bar')).to.equal({ foo: 'bar' });
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
it('should ignore invalid logfmt lines when parsing logfmt', () => {
|
|
31
|
-
const parser =
|
|
32
|
-
expect(parser(void 0)).to.be.false();
|
|
31
|
+
const parser = parseFactory('logfmt');
|
|
32
|
+
expect(parser.run(void 0)).to.be.false();
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
it('should parse regex', () => {
|
|
36
|
-
const parser =
|
|
37
|
-
expect(parser('[info 20ms] lorem ipsum dolor')).to.equal({
|
|
36
|
+
const parser = parseFactory('\\[(?<severity>\\S+)\\s*(?<delay>\\d+)ms\\] (?<message>.*)');
|
|
37
|
+
expect(parser.run('[info 20ms] lorem ipsum dolor')).to.equal({
|
|
38
38
|
severity: 'info',
|
|
39
39
|
delay: '20',
|
|
40
40
|
message: 'lorem ipsum dolor',
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
expect(parser('foo')).to.be.false();
|
|
43
|
+
expect(parser.run('foo')).to.be.false();
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
describe('tables', () => {
|
|
@@ -51,22 +51,20 @@ describe('parsers', () => {
|
|
|
51
51
|
];
|
|
52
52
|
|
|
53
53
|
it('should ignore headers', () => {
|
|
54
|
-
const
|
|
55
|
-
const parser = parse('table');
|
|
54
|
+
const parser = parseFactory('table');
|
|
56
55
|
const line = tableRows[0];
|
|
57
|
-
|
|
58
|
-
expect(parser(line, line,
|
|
56
|
+
|
|
57
|
+
expect(parser.run(line, line, null)).to.be.false();
|
|
59
58
|
});
|
|
60
59
|
|
|
61
60
|
it('should parse subsequent rows', () => {
|
|
62
|
-
const
|
|
63
|
-
const parser = parse('table');
|
|
61
|
+
const parser = parseFactory('table');
|
|
64
62
|
let line;
|
|
65
63
|
|
|
66
64
|
line = tableRows[1];
|
|
67
|
-
expect(parser(line, line,
|
|
65
|
+
expect(parser.run(line, line, tableRows[0])).to.equal({ NAME: 'foo', TYPE: 'bar' });
|
|
68
66
|
line = tableRows[2];
|
|
69
|
-
expect(parser(line, line,
|
|
67
|
+
expect(parser.run(line, line, tableRows[0])).to.equal({ NAME: 'baz', TYPE: 'qux' });
|
|
70
68
|
});
|
|
71
69
|
});
|
|
72
70
|
});
|