Skip to content

Commit 0882c08

Browse files
committed
create py.test logger
1 parent 3770a67 commit 0882c08

File tree

11 files changed

+159
-89
lines changed

11 files changed

+159
-89
lines changed

lib/create-runner.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ function createRunner(config, testFile) {
1919
return child_process_1.exec([
2020
python,
2121
'-m pytest',
22+
'-s',
2223
'--tap-stream',
2324
'-x',
2425
'--tb=no',

lib/parse-tap.js

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
11
"use strict";
2-
var isTap = /^# TAP/m;
3-
var finalTestNumber = /^1..([0-9+])$/m;
4-
var testError = /^# E\s+(.+)$/m;
5-
function formatFailureMessage(message) {
2+
var regex = {
3+
isTap: /^# TAP/m,
4+
test: /^[not ]?ok [0-9]+ -/m,
5+
finalTest: /^1..([0-9+])$/m,
6+
error: /^# E\s+(.+)$/m,
7+
log: /^(?!# TAP)(?!(not )?ok [0-9]+ -)(?!1..[0-9]+)(?!# E\s)(.*)$/
8+
};
9+
function formatFeedback(message) {
610
return message.split('_').join(' ');
711
}
12+
function log(data) {
13+
var logs = data.match(regex.log);
14+
if (logs && logs.length > 0) {
15+
logs.forEach(function (line) {
16+
try {
17+
console.dir(JSON.parse(JSON.stringify(line)));
18+
}
19+
catch (e) {
20+
console.log(data);
21+
}
22+
});
23+
}
24+
}
825
function parseTap(data) {
9-
if (!data || !data.match(isTap)) {
26+
log(data);
27+
if (!data || !data.match(regex.isTap)) {
1028
console.log('No TAP output: ', data);
1129
return;
1230
}
13-
if (!data.match(finalTestNumber)) {
31+
if (!data.match(regex.finalTest)) {
1432
console.log('Could not parse final test number: ', data);
1533
return;
1634
}
17-
var finalTest = parseInt(data.match(finalTestNumber)[1], 10);
35+
var finalTest = parseInt(data.match(regex.finalTest)[1], 10);
1836
var final = null;
19-
if (data.match(testError)) {
37+
if (data.match(regex.error)) {
2038
var failingLineRegex = new RegExp("^not ok " + finalTest + " - (.+)$", 'm');
2139
var line = data.match(failingLineRegex)[1];
2240
if (!line || typeof line !== 'string') {
@@ -26,14 +44,14 @@ function parseTap(data) {
2644
if (!taskPosition || typeof taskPosition !== 'number') {
2745
console.log('No matching taskPosition', data);
2846
}
29-
var message = formatFailureMessage(line.match(/\.test_(.+)$/)[1]);
47+
var message = formatFeedback(line.match(/\.test_(.+)$/)[1]);
3048
if (!message || typeof message !== 'string') {
3149
console.log('Error with test. There is no valid test message: ', data);
3250
message = '';
3351
}
3452
final = {
3553
completed: false,
36-
msg: formatFailureMessage(message),
54+
msg: formatFeedback(message),
3755
taskPosition: taskPosition - 1,
3856
timedOut: false
3957
};

lib/runner.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ function runner(testFile, config, handleResult) {
1010
if (!data || !data.length) {
1111
return;
1212
}
13+
console.log('data', data);
1314
final = parse_tap_1.default(data);
1415
if (!final) {
1516
console.log('Error parsing test ouptut:', data);

src/create-runner.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default function createRunner(config: CR.Config, testFile: string) {
1919
return exec([
2020
python,
2121
'-m pytest',
22+
'-s',
2223
'--tap-stream',
2324
'-x', // stop after first failure
2425
'--tb=no', // no traceback

src/parse-tap.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,50 @@
1-
const isTap = /^# TAP/m;
2-
const finalTestNumber = /^1..([0-9+])$/m;
3-
const testError = /^# E\s+(.+)$/m;
1+
const regex = {
2+
isTap: /^# TAP/m,
3+
test: /^[not ]?ok [0-9]+ -/m,
4+
finalTest: /^1..([0-9+])$/m,
5+
error: /^# E\s+(.+)$/m,
6+
log: /^(?!# TAP)(?!(not )?ok [0-9]+ -)(?!1..[0-9]+)(?!# E\s)(.*)$/
7+
};
48

5-
function formatFailureMessage(message: string): string {
9+
function formatFeedback(message: string): string {
610
return message.split('_').join(' ');
711
}
812

13+
function log(data: string): void {
14+
var logs = data.match(regex.log);
15+
if (logs && logs.length > 0) {
16+
logs.forEach((line: string) => {
17+
try {
18+
console.dir(JSON.parse(JSON.stringify(line)));
19+
} catch (e) {
20+
console.log(data);
21+
}
22+
});
23+
}
24+
}
25+
926
export default function parseTap(data: string): ParseFinal {
1027

11-
if (!data || !data.match(isTap)) {
28+
// capture any abnormal data as a log
29+
log(data);
30+
31+
if (!data || !data.match(regex.isTap)) {
1232
console.log('No TAP output: ', data);
1333
return;
1434
}
1535

16-
if (!data.match(finalTestNumber)) {
36+
if (!data.match(regex.finalTest)) {
1737
console.log('Could not parse final test number: ', data);
1838
return;
1939
}
20-
let finalTest: number = parseInt(data.match(finalTestNumber)[1], 10);
40+
41+
let finalTest: number = parseInt(data.match(regex.finalTest)[1], 10);
2142

2243
let final: ParseFinal = null;
2344

24-
if (data.match(testError)) {
45+
if (data.match(regex.error)) {
2546

26-
// fail
47+
// first FAILing test
2748

2849
let failingLineRegex = new RegExp(`^not ok ${finalTest} - (.+)$`, 'm');
2950
let line: string = data.match(failingLineRegex)[1];
@@ -36,21 +57,21 @@ export default function parseTap(data: string): ParseFinal {
3657
console.log('No matching taskPosition', data);
3758
}
3859

39-
let message: string = formatFailureMessage(line.match(/\.test_(.+)$/)[1]);
60+
let message: string = formatFeedback(line.match(/\.test_(.+)$/)[1]);
4061
if (!message || typeof message !== 'string') {
4162
console.log('Error with test. There is no valid test message: ', data);
4263
message = '';
4364
}
4465

4566
final = {
4667
completed: false,
47-
msg: formatFailureMessage(message),
68+
msg: formatFeedback(message),
4869
taskPosition: taskPosition - 1,
4970
timedOut: false // TODO
5071
};
5172
} else {
5273

53-
// all pass
74+
// all tests PASS
5475

5576
let finalPassRegex = new RegExp(`^ok ${finalTest} - (.+)$`, 'm');
5677
let line: string = data.match(finalPassRegex)[1];

src/runner.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ export default function runner(testFile: string, config: CR.Config,
1616
return;
1717
}
1818

19+
console.log('data', data);
20+
// console.log
21+
// console.dir
22+
1923
// transform data;
2024
final = parseTap(data);
2125
if (!final) {

src/typings/cr/cr.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ interface TestResult {
2222
runner?: any;
2323
taskPosition?: number;
2424
}
25-
2625
}
2726

2827
interface Process {

src/typings/cr/globals.d.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,3 @@ interface ParseFinal {
44
taskPosition: number;
55
timedOut?: boolean;
66
}
7-
8-
interface PyTest {
9-
name: string;
10-
teardown: Object;
11-
setup: Object;
12-
run_index: number;
13-
call: {
14-
duration: number;
15-
outcome: string;
16-
name: string;
17-
longrepr: string;
18-
};
19-
duration: number;
20-
outcome: string;
21-
}

test/demos/pass-log.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
a = 1;
2+
3+
class Test01Class:
4+
def test_passing_one(self):
5+
assert a == 1
6+
7+
print('Log');
8+
9+
def test_passing_test(self):
10+
assert a < 2
11+
12+
class Test02Class:
13+
def test_passing_two(self):
14+
assert a == 1
15+
16+
print('LOG2')
17+
18+
def test_passing_test(self):
19+
assert a < 2
20+
21+
class Test03Class:
22+
def test_passing_three(self):
23+
print('INNER LOG 3')
24+
assert a == 1
25+
26+
print('LOG3');
27+
28+
def test_passing_test(self):
29+
assert a < 2

test/logger.spec.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import test from 'ava';
2+
import * as path from 'path';
3+
import {
4+
getCreateRunner
5+
} from './runner-setup';
6+
7+
test('should log to the console', t => {
8+
let testFile = path.join(__dirname, 'demos', 'pass-log.py');
9+
let createRunner = getCreateRunner(testFile);
10+
t.ok(createRunner);
11+
});

test/runner.spec.js

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,56 @@ import * as fs from 'fs';
44
import exists from '../lib/exists';
55
import {getRunner} from './runner-setup';
66

7-
test('runner runs a single test to completion', async t => {
8-
let file = path.join(__dirname, 'demos', 'single-test.py');
9-
let run = await getRunner(file);
10-
let expected = {
11-
change: 1,
12-
pass: true,
13-
taskPosition: 1,
14-
msg: 'Task 1 Complete',
15-
completed: true
16-
};
17-
t.same(run, expected);
18-
});
7+
// test('runner runs a single test to completion', async t => {
8+
// let file = path.join(__dirname, 'demos', 'single-test.py');
9+
// let run = await getRunner(file);
10+
// let expected = {
11+
// change: 1,
12+
// pass: true,
13+
// taskPosition: 1,
14+
// msg: 'Task 1 Complete',
15+
// completed: true
16+
// };
17+
// t.same(run, expected);
18+
// });
1919

20-
test('runner runs three tests to completion', async t => {
21-
let file = path.join(__dirname, 'demos', 'pass-three.py');
22-
let run = await getRunner(file);
23-
let expected = {
24-
change: 3,
25-
pass: true,
26-
taskPosition: 3,
27-
msg: 'Task 3 Complete',
28-
completed: true
29-
};
30-
t.same(run, expected);
31-
});
20+
// test('runner runs three tests to completion', async t => {
21+
// let file = path.join(__dirname, 'demos', 'pass-three.py');
22+
// let run = await getRunner(file);
23+
// let expected = {
24+
// change: 3,
25+
// pass: true,
26+
// taskPosition: 3,
27+
// msg: 'Task 3 Complete',
28+
// completed: true
29+
// };
30+
// t.same(run, expected);
31+
// });
3232

33-
test('runner fails early at first failure', async t => {
34-
let file = path.join(__dirname, 'demos', 'fail-at-one.py');
35-
let run = await getRunner(file);
36-
let expected = {
37-
change: 0,
38-
pass: false,
39-
taskPosition: 0,
40-
msg: 'failing test',
41-
completed: false,
42-
timedOut: false
43-
};
44-
t.same(run, expected);
45-
});
46-
47-
test('runner fails at final test', async t => {
48-
let file = path.join(__dirname, 'demos', 'fail-at-three.py');
49-
let run = await getRunner(file);
50-
let expected = {
51-
change: 2,
52-
pass: true,
53-
taskPosition: 2,
54-
msg: 'failing test',
55-
completed: false,
56-
timedOut: false
57-
};
58-
t.same(run, expected);
59-
});
33+
// test('runner fails early at first failure', async t => {
34+
// let file = path.join(__dirname, 'demos', 'fail-at-one.py');
35+
// let run = await getRunner(file);
36+
// let expected = {
37+
// change: 0,
38+
// pass: false,
39+
// taskPosition: 0,
40+
// msg: 'failing test',
41+
// completed: false,
42+
// timedOut: false
43+
// };
44+
// t.same(run, expected);
45+
// });
46+
// //
47+
// test('runner fails at final test', async t => {
48+
// let file = path.join(__dirname, 'demos', 'fail-at-three.py');
49+
// let run = await getRunner(file);
50+
// let expected = {
51+
// change: 2,
52+
// pass: true,
53+
// taskPosition: 2,
54+
// msg: 'failing test',
55+
// completed: false,
56+
// timedOut: false
57+
// };
58+
// t.same(run, expected);
59+
// });

0 commit comments

Comments
 (0)