Commit 9bc4b586 by Gabriel Falcão

colored output almost done, and rocking out loud :)

parent 8d0b0f09
...@@ -20,6 +20,10 @@ import sys ...@@ -20,6 +20,10 @@ import sys
from lettuce.terrain import after from lettuce.terrain import after
from lettuce.terrain import before from lettuce.terrain import before
def wrt(what):
sys.stdout.write(what)
def wrap_file_and_line(string, start, end): def wrap_file_and_line(string, start, end):
return re.sub(r'([#] [^:]+[:]\d+)', '%s\g<1>%s' % (start, end), string) return re.sub(r'([#] [^:]+[:]\d+)', '%s\g<1>%s' % (start, end), string)
...@@ -32,10 +36,13 @@ def wp(l): ...@@ -32,10 +36,13 @@ def wp(l):
return l return l
def write_out(what): def write_out(what):
sys.stdout.write(wp(what)) wrt(wp(what))
@before.each_step @before.each_step
def print_step_running(step): def print_step_running(step):
if not step.defined_at:
return
string = step.represent_string(step.sentence) string = step.represent_string(step.sentence)
string = wrap_file_and_line(string, '\033[1;30m', '\033[0m') string = wrap_file_and_line(string, '\033[1;30m', '\033[0m')
write_out("\033[1;30m%s" % string) write_out("\033[1;30m%s" % string)
...@@ -50,30 +57,43 @@ def print_step_ran(step): ...@@ -50,30 +57,43 @@ def print_step_ran(step):
string = step.represent_string(step.sentence) string = step.represent_string(step.sentence)
string = wrap_file_and_line(string, '\033[1;30m', '\033[0m') if not step.failed:
string = wrap_file_and_line(string, '\033[1;30m', '\033[0m')
prefix = '\033[A'
if step.failed: if step.failed:
color = "\033[0;31m" color = "\033[0;31m"
else: string = wrap_file_and_line(string, '\033[1;41;33m', '\033[0m')
elif step.passed:
color = "\033[1;32m" color = "\033[1;32m"
write_out("\033[A%s%s" % (color, string)) elif step.defined_at:
color = "\033[0;36m"
else:
color = "\033[0;33m"
prefix = ""
write_out("%s%s%s" % (prefix, color, string))
if step.data_list: if step.data_list:
for line in step.represent_data_list().splitlines(): for line in step.represent_data_list().splitlines():
write_out("%s%s\033[0m\n" % (color, line)) write_out("%s%s\033[0m\n" % (color, line))
if step.failed: if step.failed:
sys.stdout.write(color) wrt("\033[1;31m")
pspaced = lambda x: sys.stdout.write("%s%s" % (" " * step.indentation, x)) pspaced = lambda x: wrt("%s%s" % (" " * step.indentation, x))
lines = step.why.traceback.splitlines() lines = step.why.traceback.splitlines()
for pindex, line in enumerate(lines): for pindex, line in enumerate(lines):
pspaced(line) pspaced(line)
if pindex + 1 < len(lines): if pindex + 1 < len(lines):
sys.stdout.write("\n") wrt("\n")
sys.stdout.write("\033[0m\n") wrt("\033[0m\n")
@before.each_scenario @before.each_scenario
def print_scenario_running(scenario): def print_scenario_running(scenario):
...@@ -98,29 +118,69 @@ def print_end(total): ...@@ -98,29 +118,69 @@ def print_end(total):
write_out("\n") write_out("\n")
word = total.features_ran > 1 and "features" or "feature" word = total.features_ran > 1 and "features" or "feature"
write_out("\033[1;37m%d %s (\033[1;32m%d passed\033[1;37m)\033[0m\n" % (
color = "\033[1;32m"
if total.features_passed is 0:
color = "\033[0;31m"
write_out("\033[1;37m%d %s (%s%d passed\033[1;37m)\033[0m\n" % (
total.features_ran, total.features_ran,
word, word,
color,
total.features_passed total.features_passed
) )
) )
color = "\033[1;32m"
if total.scenarios_passed is 0:
color = "\033[0;31m"
word = total.scenarios_ran > 1 and "scenarios" or "scenario" word = total.scenarios_ran > 1 and "scenarios" or "scenario"
write_out("\033[1;37m%d %s (\033[1;32m%d passed\033[1;37m)\033[0m\n" % ( write_out("\033[1;37m%d %s (%s%d passed\033[1;37m)\033[0m\n" % (
total.scenarios_ran, total.scenarios_ran,
word, word,
color,
total.scenarios_passed total.scenarios_passed
) )
) )
steps_details = []
kinds_and_colors = {
'failed': '\033[0;31m',
'skipped': '\033[0;36m',
'undefined': '\033[0;33m'
}
for kind, color in kinds_and_colors.items():
attr = 'steps_%s' % kind
stotal = getattr(total, attr)
if stotal:
steps_details.append(
"%s%d %s" % (color, stotal, kind)
)
steps_details.append("\033[1;32m%d passed\033[1;37m" % total.steps_passed)
word = total.steps > 1 and "steps" or "step" word = total.steps > 1 and "steps" or "step"
write_out("\033[1;37m%d %s (\033[1;32m%d passed\033[1;37m)\033[0m\n" % ( content = "\033[1;37m, ".join(steps_details)
word = total.steps > 1 and "steps" or "step"
write_out("\033[1;37m%d %s (%s)\033[0m\n" % (
total.steps, total.steps,
word, word,
total.steps_passed content
) )
) )
if total.proposed_definitions:
wrt("\n\033[0;33mYou can implement step definitions for undefined steps with these snippets:\n\n")
wrt("from lettuce import step\n\n")
for step in total.proposed_definitions:
method_name = "_".join(re.findall("\w+", step.sentence)).lower()
wrt("@step(r'%s')\n" % re.escape(step.sentence).replace(r'\ ', ' '))
wrt("def %s(step):\n" % method_name)
wrt(" pass\033[0m\n")
def print_no_features_found(where): def print_no_features_found(where):
where = os.path.relpath(where) where = os.path.relpath(where)
if not where.startswith(os.sep): if not where.startswith(os.sep):
......
...@@ -433,8 +433,8 @@ def test_output_with_failed_colorful_with_table(): ...@@ -433,8 +433,8 @@ def test_output_with_failed_colorful_with_table():
"\033[1;30m Given I have a dumb step that passes \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:20\033[0m\n" "\033[1;30m Given I have a dumb step that passes \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:20\033[0m\n"
"\033[A\033[1;32m Given I have a dumb step that passes \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:20\033[0m\n" "\033[A\033[1;32m Given I have a dumb step that passes \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:20\033[0m\n"
"\033[1;30m And this one fails \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:24\033[0m\n" "\033[1;30m And this one fails \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:24\033[0m\n"
"\033[A\033[0;31m And this one fails \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:24\033[0m\n" "\033[A\033[0;31m And this one fails \033[1;41;33m# tests/functional/output_features/failed_table/failed_table_steps.py:24\033[0m\n"
"\033[0;31m Traceback (most recent call last):\n" "\033[1;31m Traceback (most recent call last):\n"
' File "%(lettuce_core_file)s", line 54, in __call__\n' ' File "%(lettuce_core_file)s", line 54, in __call__\n'
" ret = self.function(self.step, *args, **kw)\n" " ret = self.function(self.step, *args, **kw)\n"
' File "%(step_file)s", line 25, in tof\n' ' File "%(step_file)s", line 25, in tof\n'
...@@ -442,13 +442,13 @@ def test_output_with_failed_colorful_with_table(): ...@@ -442,13 +442,13 @@ def test_output_with_failed_colorful_with_table():
" AssertionError\033[0m\n" " AssertionError\033[0m\n"
"\033[1;30m Then this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n" "\033[1;30m Then this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n"
"\033[A\033[0;36m Then this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n" "\033[A\033[0;36m Then this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n"
"\033[1;30m And this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[1;30m\n" "\033[1;30m And this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n"
"\033[A\033[1;36m And this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n" "\033[A\033[0;36m And this one will be skipped \033[1;30m# tests/functional/output_features/failed_table/failed_table_steps.py:28\033[0m\n"
"\033[0;33m And this one does not even has definition \033[1;30m# tests/functional/output_features/failed_table/failed_table.feature:12\033[0m\n" "\033[0;33m And this one does not even has definition \033[1;30m# tests/functional/output_features/failed_table/failed_table.feature:12\033[0m\n"
"\n" "\n"
"\033[1;37m1 feature (\033[0;31m0 passed\033[1;37m)\033[0m\n" "\033[1;37m1 feature (\033[0;31m0 passed\033[1;37m)\033[0m\n"
"\033[1;37m1 scenario (\033[0;31m0 passed\033[1;37m)\033[0m\n" "\033[1;37m1 scenario (\033[0;31m0 passed\033[1;37m)\033[0m\n"
"\033[1;37m5 steps (\033[0;31m1 failed\033[1;37m, \033[0;36mm2 skipped\033[1;37m, \033[0;33m1 undefined\033[1;37m, \033[1;32m1 passed\033[1;37m)\033[0m\n" "\033[1;37m5 steps (\033[0;31m1 failed\033[1;37m, \033[0;36m2 skipped\033[1;37m, \033[0;33m1 undefined\033[1;37m, \033[1;32m1 passed\033[1;37m)\033[0m\n"
"\n" "\n"
"\033[0;33mYou can implement step definitions for undefined steps with these snippets:\n" "\033[0;33mYou can implement step definitions for undefined steps with these snippets:\n"
"\n" "\n"
...@@ -456,8 +456,8 @@ def test_output_with_failed_colorful_with_table(): ...@@ -456,8 +456,8 @@ def test_output_with_failed_colorful_with_table():
"\n" "\n"
"@step(r'And this one does not even has definition')\n" "@step(r'And this one does not even has definition')\n"
"def and_this_one_does_not_even_has_definition(step):\n" "def and_this_one_does_not_even_has_definition(step):\n"
" pass\n" " pass\033[0m"
"\033[0m" % { "\n" % {
'lettuce_core_file':'/Users/gabriel.falcao/Projetos/lettuce/lettuce/core.py', 'lettuce_core_file':'/Users/gabriel.falcao/Projetos/lettuce/lettuce/core.py',
'step_file': '/Users/gabriel.falcao/Projetos/lettuce/tests/functional/output_features/failed_table/failed_table_steps.py' 'step_file': '/Users/gabriel.falcao/Projetos/lettuce/tests/functional/output_features/failed_table/failed_table_steps.py'
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment