Skip to content

Commit d22baf5

Browse files
committed
fix(behave): fix the mangling of error messages of the pretty formatter
… I don't understand why this bug has been alive for years. The Formatter interface is well-thought, thankfully.
1 parent 9268cd5 commit d22baf5

4 files changed

Lines changed: 91 additions & 4 deletions

File tree

.behaverc

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
; We are not using the default path to leave room for unit tests ; also, apps.
33
paths = tests/acceptance
44

5-
65
# What is going on? Does this change anything for you? --format=plain works
76
;format = plain
87

@@ -11,10 +10,18 @@ paths = tests/acceptance
1110
;logging_filter = -suds
1211

1312
; Show all print() statements even if tests pass. (bugs! bugs!)
14-
;stderr_capture = False
13+
stderr_capture = False
1514
stdout_capture = False
16-
;log_capture = False
15+
log_capture = False
16+
1717

18+
show_timings = False
19+
show_source = False
20+
show_multiline = True
1821
show_skipped = False
1922
show_snippets = False
20-
summary = True
23+
summary = True
24+
25+
[behave.formatters]
26+
# We override the buggy "pretty" formatter
27+
pretty = tests.acceptance.formatter:BeautifulFormatter

tests/__init__.py

Whitespace-only changes.

tests/acceptance/__init__.py

Whitespace-only changes.

tests/acceptance/formatter.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import six
2+
from behave.formatter.pretty import PrettyFormatter
3+
from behave.formatter.base import Formatter
4+
from behave.textutil import indent
5+
6+
7+
class BeautifulFormatter(PrettyFormatter):
8+
"""
9+
Quick patch for the most annoying bug of the PrettyFormatter.
10+
Eventually we should move to our own CustomFormatter,
11+
so that captured logs and stdout are printed AFTER the step,
12+
like in high-quality gherkin runners in other languages.
13+
"""
14+
def result(self, step):
15+
if not self.monochrome:
16+
lines = self.step_lines + 1
17+
if self.show_multiline:
18+
if step.table:
19+
lines += len(step.table.rows) + 1
20+
if step.text:
21+
lines += len(step.text.splitlines()) + 2
22+
# self.stream.write(up(lines)) # NO GOD PLEASE NO
23+
arguments = []
24+
location = None
25+
if self._match:
26+
arguments = self._match.arguments
27+
location = self._match.location
28+
self.print_step(step.status, arguments, location, True)
29+
if step.error_message:
30+
self.stream.write(indent(step.error_message.strip(), u" "))
31+
self.stream.write("\n\n")
32+
self.stream.flush()
33+
34+
def match(self, match):
35+
self._match = match
36+
self.print_statement()
37+
self.stream.flush()
38+
39+
40+
class CustomFormatter(Formatter):
41+
"""
42+
Half-assed attempt at making our own formatter entirely.
43+
We don't use this for now, we're using the BeautifulFormatter above.
44+
"""
45+
46+
# indentation = "\t"
47+
indentation = " "
48+
49+
def indent(self, text):
50+
p = self.indentation
51+
lines = text.split("\n")
52+
return "\n".join(["%s%s" % ("" if "" == line else p, line) for line in lines])
53+
54+
def feature(self, feature):
55+
self.stream.write(u"\n")
56+
self.stream.write(u"%s: %s\n" % (
57+
feature.keyword,
58+
feature.name,
59+
))
60+
for line in feature.description:
61+
self.stream.write(self.indent(u"%s\n" % line))
62+
self.stream.flush()
63+
64+
def scenario(self, scenario):
65+
self.stream.write(u"\n")
66+
self.stream.write(u"%s: %s\n" % (
67+
scenario.keyword,
68+
scenario.name,
69+
))
70+
self.stream.flush()
71+
72+
def result(self, step):
73+
self.stream.write(self.indent(u"%s %s\n" % (
74+
step.keyword,
75+
step.name,
76+
)))
77+
if step.error_message:
78+
self.stream.write(self.indent(step.error_message.strip()))
79+
self.stream.write("\n")
80+
self.stream.flush()

0 commit comments

Comments
 (0)