Skip to content
Browse files

Assorted bits of code cleanup; mainly better PEP8.

- Insert blank lines where missing
- Remove surplus blank lines
- Remove some unused imports
- Remove the use of the ``string`` module from lettuce.strings (work on the ``str`` objects directly which is just what ``string`` does - it's mostly obsolete now)
- Reshuffled a few bits of code to use ``all()`` or ``any()`` where appropriate and *not* use them where inappropriate

No functionality changes. (All tests still pass.)
  • Loading branch information...
1 parent 7436c4b commit 37d5a910755be0612b26e3cb62301d78201d4206 @chris-morgan chris-morgan committed Jul 30, 2011
View
64 lettuce/core.py
@@ -32,6 +32,7 @@
fs = FileSystem()
+
class HashList(list):
__base_msg = 'The step "%s" have no table defined, so ' \
'that you can\'t use step.hashes.%s'
@@ -64,6 +65,7 @@ def last(self):
raise AssertionError(self.__base_msg % (self.step.sentence, 'last'))
+
class Language(object):
code = 'en'
name = 'English'
@@ -73,6 +75,7 @@ class Language(object):
examples = 'Examples|Scenarios'
scenario_outline = 'Scenario Outline'
scenario_separator = 'Scenario( Outline)?'
+
def __init__(self, code=u'en'):
self.code = code
for attr, value in languages.LANGUAGES[code].items():
@@ -98,6 +101,7 @@ def guess_from_string(cls, string):
return instance
+
class StepDefinition(object):
"""A step definition is a wrapper for user-defined callbacks. It
gets a few metadata from file, such as filename and line number"""
@@ -122,6 +126,7 @@ def __call__(self, *args, **kw):
return ret
+
class StepDescription(object):
"""A simple object that holds filename and line number of a step
description (step within feature file)"""
@@ -132,6 +137,7 @@ def __init__(self, line, filename):
self.line = line
+
class ScenarioDescription(object):
"""A simple object that holds filename and line number of a scenario
description (scenario within feature file)"""
@@ -146,6 +152,7 @@ def __init__(self, scenario, filename, string, language):
self.line = pline + 1
break
+
class FeatureDescription(object):
"""A simple object that holds filename and line number of a feature
description"""
@@ -168,6 +175,7 @@ def __init__(self, feature, filename, string, language):
self.description_at = tuple(described_at)
+
class Step(object):
""" Object that represents each step on feature files."""
has_definition = False
@@ -198,8 +206,8 @@ def propose_definition(self):
method_name = sentence
groups = [
- ('"', re.compile(r'("[^"]+")')), # double quotes
- ("'", re.compile(r"('[^']+')")), # single quotes
+ ('"', re.compile(r'("[^"]+")')), # double quotes
+ ("'", re.compile(r"('[^']+')")), # single quotes
]
attribute_names = []
@@ -217,21 +225,19 @@ def propose_definition(self):
method_name = method_name.replace(match, group_name)
attribute_names.append(group_name)
-
-
method_name = unicodedata.normalize('NFKD', method_name) \
.encode('ascii', 'ignore')
method_name = '%s(step%s)' % (
"_".join(re.findall("\w+", method_name)).lower(),
- attribute_names and (", %s" % ", ".join(attribute_names)) or ""
- )
+ attribute_names and (", %s" % ", ".join(attribute_names)) or "")
return method_name, sentence
def solve_and_clone(self, data):
sentence = self.sentence
hashes = self.hashes[:] # deep copy
for k, v in data.items():
+
def evaluate(stuff):
return stuff.replace(u'<%s>' % unicode(k), unicode(v))
@@ -387,7 +393,7 @@ def run(self, ignore_case):
return True
@staticmethod
- def run_all(steps, outline = None, run_callbacks = False, ignore_case = True):
+ def run_all(steps, outline=None, run_callbacks=False, ignore_case=True):
"""Runs each step in the given list of steps.
Returns a tuple of five lists:
@@ -434,7 +440,7 @@ def run_all(steps, outline = None, run_callbacks = False, ignore_case = True):
return (all_steps, steps_passed, steps_failed, steps_undefined, reasons_to_fail)
@classmethod
- def many_from_lines(klass, lines, filename = None, original_string = None):
+ def many_from_lines(klass, lines, filename=None, original_string=None):
"""Parses a set of steps from lines of input.
This will correctly parse and produce a list of steps from lines without
@@ -652,18 +658,16 @@ def run_scenario(almost_self, order=-1, outline=None, run_callbacks=False):
steps_skipped = filter(skip, all_steps)
if outline:
- call_hook(
- 'outline', 'scenario', self, order, outline, reasons_to_fail
- )
+ call_hook('outline', 'scenario', self, order, outline,
+ reasons_to_fail)
return ScenarioResult(
self,
steps_passed,
steps_failed,
steps_skipped,
steps_undefined,
- True
- )
+ True)
if self.outlines:
first = True
@@ -757,14 +761,15 @@ def from_string(new_scenario, string, tags=None, with_file=None, original_string
with_file=with_file,
original_string=original_string,
language=language,
- tags=tags
- )
+ tags=tags)
return scenario
+
class Feature(object):
""" Object that represents a feature."""
described_at = None
+
def __init__(self, name, remaining_lines, with_file, original_string,
language=None, tags=None):
@@ -778,8 +783,7 @@ def __init__(self, name, remaining_lines, with_file, original_string,
self.scenarios, self.description = self._parse_remaining_lines(
remaining_lines,
original_string,
- with_file
- )
+ with_file)
self.original_string = original_string
@@ -841,17 +845,12 @@ def from_string(new_feature, string, with_file=None, language=None):
found = len(re.findall(r'%s:[ ]*\w+' % language.feature, "\n".join(lines), re.U))
if found > 1:
- raise LettuceSyntaxError(
- with_file,
- 'A feature file must contain ONLY ONE feature!'
- )
+ raise LettuceSyntaxError(with_file,
+ 'A feature file must contain ONLY ONE feature!')
elif found == 0:
- raise LettuceSyntaxError(
- with_file,
- 'Features must have a name. e.g: "Feature: This is my name"'
- )
-
+ raise LettuceSyntaxError(with_file,
+ 'Features must have a name. e.g: "Feature: This is my name"')
while lines:
matched = re.search(r'%s:(.*)' % language.feature, lines[0], re.I)
@@ -898,15 +897,12 @@ def _parse_remaining_lines(self, lines, original_string, with_file=None):
parts = strings.split_scenarios(lines, scenario_prefix)
- scenario_strings = [
- u"%s" % (s) for s in parts if s.strip()
- ]
+ scenario_strings = [u"%s" % (s) for s in parts if s.strip()]
kw = dict(
original_string=original_string,
with_file=with_file,
language=self.language,
- tags=self.tags
- )
+ tags=self.tags)
scenarios = [Scenario.from_string(s, **kw) for s in scenario_strings]
@@ -932,6 +928,7 @@ def run(self, scenarios=None, run_controller=None, ignore_case=True):
call_hook('after_each', 'feature', self)
return FeatureResult(self, *scenarios_ran)
+
class FeatureResult(object):
"""Object that holds results of each scenario ran from within a feature"""
def __init__(self, feature, *scenario_results):
@@ -942,6 +939,7 @@ def __init__(self, feature, *scenario_results):
def passed(self):
return all([result.passed for result in self.scenario_results])
+
class ScenarioResult(object):
"""Object that holds results of each step ran from within a scenario"""
def __init__(self, scenario, steps_passed, steps_failed, steps_skipped,
@@ -966,14 +964,15 @@ def passed(self):
def failed(self):
return len(self.steps_failed) > 0
+
class TotalResult(object):
def __init__(self, feature_results):
self.feature_results = feature_results
self.scenario_results = []
self.steps_passed = 0
self.steps_failed = 0
self.steps_skipped = 0
- self.steps_undefined= 0
+ self.steps_undefined = 0
self._proposed_definitions = []
self.steps = 0
for feature_result in self.feature_results:
@@ -986,7 +985,6 @@ def __init__(self, feature_results):
self.steps += scenario_result.total_steps
self._proposed_definitions.extend(scenario_result.steps_undefined)
-
def _filter_proposed_definitions(self):
sentences = []
for step in self._proposed_definitions:
View
1 lettuce/decorators.py
@@ -18,6 +18,7 @@
from lettuce.core import STEP_REGISTRY
from lettuce.exceptions import StepLoadingError
+
def step(regex):
"""Decorates a function, so that it will become a new step
definition.
View
7 lettuce/django/apps.py
@@ -19,11 +19,13 @@
from django.utils.importlib import import_module
from django.conf import settings
+
def _filter_bultins(module):
"returns only those apps that are not builtin django.contrib"
name = module.__name__
return not name.startswith("django.contrib") and name != 'lettuce.django'
+
def _filter_configured_apps(module):
"returns only those apps that are in django.conf.settings.LETTUCE_APPS"
app_found = True
@@ -35,6 +37,7 @@ def _filter_configured_apps(module):
return app_found
+
def _filter_configured_avoids(module):
"returns apps that are not within django.conf.settings.LETTUCE_AVOID_APPS"
run_app = False
@@ -45,9 +48,11 @@ def _filter_configured_avoids(module):
return not run_app
+
def get_apps():
return map(import_module, settings.INSTALLED_APPS)
+
def harvest_lettuces(only_the_apps=None, avoid_apps=None, path="features"):
"""gets all installed apps that are not from django.contrib
returns a list of tuples with (path_to_app, app_module)
@@ -56,6 +61,7 @@ def harvest_lettuces(only_the_apps=None, avoid_apps=None, path="features"):
apps = get_apps()
if isinstance(only_the_apps, tuple) and any(only_the_apps):
+
def _filter_only_specified(module):
return module.__name__ in only_the_apps
apps = filter(_filter_only_specified, apps)
@@ -65,6 +71,7 @@ def _filter_only_specified(module):
apps = filter(_filter_configured_avoids, apps)
if isinstance(avoid_apps, tuple) and any(avoid_apps):
+
def _filter_avoid(module):
return module.__name__ not in avoid_apps
View
4 lettuce/django/management/commands/harvest.py
@@ -28,6 +28,7 @@
from lettuce.django import server
from lettuce.django import harvest_lettuces
+
class Command(BaseCommand):
help = u'Run lettuce tests all along installed apps'
args = '[PATH to feature file or folder]'
@@ -59,6 +60,7 @@ class Command(BaseCommand):
make_option('--xunit-file', action='store', dest='xunit_file', default=None,
help='Write JUnit XML to this file. Defaults to lettucetests.xml'),
)
+
def stopserver(self, failed=False):
raise SystemExit(int(failed))
@@ -71,7 +73,7 @@ def get_paths(self, args, apps_to_run, apps_to_avoid):
else:
paths = args
else:
- paths = harvest_lettuces(apps_to_run, apps_to_avoid) # list of tuples with (path, app_module)
+ paths = harvest_lettuces(apps_to_run, apps_to_avoid) # list of tuples with (path, app_module)
return paths
View
14 lettuce/django/server.py
@@ -128,18 +128,12 @@ def wait(self):
self.lock.acquire()
def should_serve_static_files(self):
- conditions = [
- StaticFilesHandler is not None,
- getattr(settings, 'STATIC_URL', False),
- ]
- return all(conditions)
+ return (StaticFilesHandler is not None and
+ getattr(settings, 'STATIC_URL', False))
def should_serve_admin_media(self):
- conditions = [
- 'django.contrib.admin' in settings.INSTALLED_APPS,
- getattr(settings, 'LETTUCE_SERVE_ADMIN_MEDIA', False),
- ]
- return any(conditions)
+ return ('django.contrib.admin' in settings.INSTALLED_APPS or
+ getattr(settings, 'LETTUCE_SERVE_ADMIN_MEDIA', False))
def run(self):
self.lock.acquire()
View
6 lettuce/exceptions.py
@@ -16,6 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import traceback
+
class NoDefinitionFound(Exception):
""" Exception raised by lettuce.core.Step, when trying to solve a
Step, but does not find a suitable step definition.
@@ -26,8 +27,8 @@ class NoDefinitionFound(Exception):
def __init__(self, step):
self.step = step
super(NoDefinitionFound, self).__init__(
- 'The step r"%s" is not defined' % self.step.sentence
- )
+ 'The step r"%s" is not defined' % self.step.sentence)
+
class ReasonToFail(object):
""" Exception that contains detailed information about a
@@ -39,6 +40,7 @@ def __init__(self, exc):
self.cause = unicode(exc)
self.traceback = traceback.format_exc(exc)
+
class LettuceSyntaxError(SyntaxError):
def __init__(self, filename, string):
self.filename = filename
View
5 lettuce/fs.py
@@ -25,6 +25,7 @@
from glob import glob
from os.path import abspath, join, dirname, curdir, exists
+
class FeatureLoader(object):
"""Loader class responsible for findind features and step
definitions along a given path on filesystem"""
@@ -47,13 +48,14 @@ def find_and_load_step_definitions(self):
else:
raise e
- reload(module) # always take fresh meat :)
+ reload(module) # always take fresh meat :)
sys.path.remove(root)
def find_feature_files(self):
paths = FileSystem.locate(self.base_dir, "*.feature")
return paths
+
class FileSystem(object):
"""File system abstraction, mainly used for indirection, so that
lettuce can be well unit-tested :)
@@ -229,4 +231,3 @@ def open_raw(cls, name, mode):
path = cls.current_dir(name)
return open(path, mode)
-
View
6 lettuce/lettuce_cli.py
@@ -21,12 +21,12 @@
import lettuce
+
def main(args=sys.argv[1:]):
base_path = os.path.join(os.path.dirname(os.curdir), 'features')
parser = optparse.OptionParser(
usage="%prog or type %prog -h (--help) for help",
- version=lettuce.version
- )
+ version=lettuce.version)
parser.add_option("-v", "--verbosity",
dest="verbosity",
@@ -74,7 +74,7 @@ def main(args=sys.argv[1:]):
verbosity=options.verbosity,
enable_xunit=options.enable_xunit,
xunit_filename=options.xunit_file,
- run_controller = run_controller)
+ run_controller=run_controller)
result = runner.run()
if not result or result.steps != result.steps_passed:
View
34 lettuce/plugins/colored_shell_output.py
@@ -17,8 +17,6 @@
import os
import re
import sys
-import platform
-import struct
from lettuce import core
from lettuce import strings
@@ -27,12 +25,15 @@
from lettuce.terrain import after
from lettuce.terrain import before
+
def wrt(what):
sys.stdout.write(what.encode('utf-8'))
+
def wrap_file_and_line(string, start, end):
return re.sub(r'([#] [^:]+[:]\d+)', '%s\g<1>%s' % (start, end), string)
+
def wp(l):
if l.startswith("\033[1;32m"):
l = l.replace(" |", "\033[1;37m |\033[1;32m")
@@ -47,9 +48,11 @@ def wp(l):
return l
+
def write_out(what):
wrt(wp(what))
+
@before.each_step
def print_step_running(step):
if not step.defined_at:
@@ -67,6 +70,7 @@ def print_step_running(step):
for line in step.represent_hashes().splitlines():
write_out("\033[1;30m%s\033[0m\n" % line)
+
@after.each_step
def print_step_ran(step):
if step.scenario.outlines:
@@ -80,7 +84,6 @@ def print_step_ran(step):
if not step.failed:
string = wrap_file_and_line(string, '\033[1;30m', '\033[0m')
-
prefix = '\033[A'
width, height = terminal.get_size()
lines_up = len(string) / float(width)
@@ -123,12 +126,14 @@ def print_step_ran(step):
wrt("\033[0m\n")
+
@before.each_scenario
def print_scenario_running(scenario):
string = scenario.represented()
string = wrap_file_and_line(string, '\033[1;30m', '\033[0m')
write_out("\n\033[1;37m%s" % string)
+
@after.outline
def print_outline(scenario, order, outline, reasons_to_fail):
table = strings.dicts_to_string(scenario.outlines, scenario.keys)
@@ -155,6 +160,7 @@ def print_outline(scenario, order, outline, reasons_to_fail):
wrt("\033[0m\n")
+
@before.each_feature
def print_feature_running(feature):
string = feature.represented()
@@ -165,6 +171,7 @@ def print_feature_running(feature):
line = wrap_file_and_line(line, '\033[1;30m', '\033[0m')
write_out("\033[1;37m%s\n" % line)
+
@after.all
def print_end(total):
write_out("\n")
@@ -179,9 +186,7 @@ def print_end(total):
total.features_ran,
word,
color,
- total.features_passed
- )
- )
+ total.features_passed))
color = "\033[1;32m"
if total.scenarios_passed is 0:
@@ -192,9 +197,7 @@ def print_end(total):
total.scenarios_ran,
word,
color,
- total.scenarios_passed
- )
- )
+ total.scenarios_passed))
steps_details = []
kinds_and_colors = {
@@ -203,14 +206,11 @@ def print_end(total):
'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("%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"
@@ -220,9 +220,7 @@ def print_end(total):
write_out("\033[1;37m%d %s (%s)\033[0m\n" % (
total.steps,
word,
- content
- )
- )
+ content))
if total.proposed_definitions:
wrt("\n\033[0;33mYou can implement step definitions for undefined steps with these snippets:\n\n")
@@ -240,6 +238,7 @@ def print_end(total):
wrt("\n")
+
def print_no_features_found(where):
where = core.fs.relpath(where)
if not where.startswith(os.sep):
@@ -248,5 +247,4 @@ def print_no_features_found(where):
write_out('\033[1;31mOops!\033[0m\n')
write_out(
'\033[1;37mcould not find features at '
- '\033[1;33m%s\033[0m\n' % where
- )
+ '\033[1;33m%s\033[0m\n' % where)
View
27 lettuce/plugins/dots.py
@@ -23,9 +23,11 @@
failed_scenarios = []
scenarios_and_its_fails = {}
+
def wrt(string):
sys.stdout.write(string)
+
@after.each_step
def print_scenario_ran(step):
if not step.failed:
@@ -40,6 +42,7 @@ def print_scenario_ran(step):
else:
wrt("E")
+
@after.all
def print_end(total):
if total.scenarios_passed < total.scenarios_ran:
@@ -54,43 +57,33 @@ def print_end(total):
wrt("%d %s (%d passed)\n" % (
total.features_ran,
word,
- total.features_passed
- )
- )
+ total.features_passed))
word = total.scenarios_ran > 1 and "scenarios" or "scenario"
wrt("%d %s (%d passed)\n" % (
total.scenarios_ran,
word,
- total.scenarios_passed
- )
- )
+ total.scenarios_passed))
steps_details = []
- for kind in ("failed","skipped", "undefined"):
+ for kind in "failed", "skipped", "undefined":
attr = 'steps_%s' % kind
stotal = getattr(total, attr)
if stotal:
- steps_details.append(
- "%d %s" % (stotal, kind)
- )
+ steps_details.append("%d %s" % (stotal, kind))
steps_details.append("%d passed" % total.steps_passed)
word = total.steps > 1 and "steps" or "step"
wrt("%d %s (%s)\n" % (
total.steps,
word,
- ", ".join(steps_details)
- )
- )
+ ", ".join(steps_details)))
+
def print_no_features_found(where):
where = core.fs.relpath(where)
if not where.startswith(os.sep):
where = '.%s%s' % (os.sep, where)
wrt('Oops!\n')
- wrt(
- 'could not find features at '
- '%s\n' % where
- )
+ wrt('could not find features at %s\n' % where)
View
22 lettuce/plugins/non_verbose.py
@@ -20,50 +20,50 @@
from lettuce.terrain import after
from lettuce.terrain import before
+
@before.each_step
def print_step_running(step):
logging.info(step.represent_string(step.sentence))
+
@after.each_step
def print_step_ran(step):
logging.info("\033[A" + step.represent_string(step.sentence))
+
@before.each_scenario
def print_scenario_running(scenario):
logging.info(scenario.represented())
+
@before.each_feature
def print_feature_running(feature):
logging.info("\n")
logging.info(feature.represented())
logging.info("\n")
+
@after.all
def print_end(total):
logging.info("\n")
word = total.features_ran > 1 and "features" or "feature"
logging.info("%d %s (%d passed)\n" % (
total.features_ran,
word,
- total.features_passed
- )
- )
+ total.features_passed))
word = total.scenarios_ran > 1 and "scenarios" or "scenario"
logging.info("%d %s (%d passed)\n" % (
total.scenarios_ran,
word,
- total.scenarios_passed
- )
- )
+ total.scenarios_passed))
word = total.steps > 1 and "steps" or "step"
logging.info("%d %s (%d passed)\n" % (
total.steps,
word,
- total.steps_passed
- )
- )
+ total.steps_passed))
+
def print_no_features_found(where):
where = core.fs.relpath(where)
@@ -73,6 +73,4 @@ def print_no_features_found(where):
logging.info('\033[1;31mOops!\033[0m\n')
logging.info(
'\033[1;37mcould not find features at '
- '\033[1;33m%s\033[0m\n' % where
- )
-
+ '\033[1;33m%s\033[0m\n' % where)
View
34 lettuce/plugins/scenario_names.py
@@ -24,13 +24,16 @@
failed_scenarios = []
scenarios_and_its_fails = {}
+
def wrt(string):
sys.stdout.write(string.encode('utf-8'))
+
@before.each_scenario
def print_scenario_running(scenario):
wrt('%s ... ' % scenario.name)
+
@after.each_scenario
def print_scenario_ran(scenario):
if scenario.passed:
@@ -42,16 +45,18 @@ def print_scenario_ran(scenario):
else:
print "ERROR"
+
@after.each_step
def save_step_failed(step):
if step.failed and step.scenario not in failed_scenarios:
scenarios_and_its_fails[step.scenario] = step.why
failed_scenarios.append(step.scenario)
+
@after.all
def print_end(total):
if total.scenarios_passed < total.scenarios_ran:
- print # just a line to separate things here
+ print # just a line to separate things here
for scenario in failed_scenarios:
reason = scenarios_and_its_fails[scenario]
wrt(reason.traceback)
@@ -61,43 +66,30 @@ def print_end(total):
wrt("%d %s (%d passed)\n" % (
total.features_ran,
word,
- total.features_passed
- )
- )
+ total.features_passed))
word = total.scenarios_ran > 1 and "scenarios" or "scenario"
wrt("%d %s (%d passed)\n" % (
total.scenarios_ran,
word,
- total.scenarios_passed
- )
- )
+ total.scenarios_passed))
steps_details = []
- for kind in ("failed","skipped", "undefined"):
+ for kind in "failed", "skipped", "undefined":
attr = 'steps_%s' % kind
stotal = getattr(total, attr)
if stotal:
- steps_details.append(
- "%d %s" % (stotal, kind)
- )
+ steps_details.append("%d %s" % (stotal, kind))
steps_details.append("%d passed" % total.steps_passed)
word = total.steps > 1 and "steps" or "step"
- wrt("%d %s (%s)\n" % (
- total.steps,
- word,
- ", ".join(steps_details)
- )
- )
+ wrt("%d %s (%s)\n" % (total.steps, word, ", ".join(steps_details)))
+
def print_no_features_found(where):
where = core.fs.relpath(where)
if not where.startswith(os.sep):
where = '.%s%s' % (os.sep, where)
wrt('Oops!\n')
- wrt(
- 'could not find features at '
- '%s\n' % where
- )
+ wrt('could not find features at %s\n' % where)
View
29 lettuce/plugins/shell_output.py
@@ -22,9 +22,11 @@
from lettuce.terrain import after
from lettuce.terrain import before
+
def wrt(what):
sys.stdout.write(what.encode('utf-8'))
+
@after.each_step
def print_step_running(step):
wrt(step.represent_string(step.original_sentence).rstrip())
@@ -41,11 +43,13 @@ def print_step_running(step):
for line in step.why.traceback.splitlines():
print_spaced(line)
+
@before.each_scenario
def print_scenario_running(scenario):
wrt('\n')
wrt(scenario.represented())
+
@after.outline
def print_outline(scenario, order, outline, reasons_to_fail):
table = strings.dicts_to_string(scenario.outlines, scenario.keys)
@@ -66,47 +70,41 @@ def print_outline(scenario, order, outline, reasons_to_fail):
for line in elines:
print_spaced(line)
+
@before.each_feature
def print_feature_running(feature):
wrt("\n")
wrt(feature.represented())
+
@after.all
def print_end(total):
wrt("\n")
word = total.features_ran > 1 and "features" or "feature"
wrt("%d %s (%d passed)\n" % (
total.features_ran,
word,
- total.features_passed
- )
- )
+ total.features_passed))
word = total.scenarios_ran > 1 and "scenarios" or "scenario"
wrt("%d %s (%d passed)\n" % (
total.scenarios_ran,
word,
- total.scenarios_passed
- )
- )
+ total.scenarios_passed))
steps_details = []
for kind in ("failed", "skipped", "undefined"):
attr = 'steps_%s' % kind
stotal = getattr(total, attr)
if stotal:
- steps_details.append(
- "%d %s" % (stotal, kind)
- )
+ steps_details.append("%d %s" % (stotal, kind))
steps_details.append("%d passed" % total.steps_passed)
word = total.steps > 1 and "steps" or "step"
wrt("%d %s (%s)\n" % (
total.steps,
word,
- ", ".join(steps_details)
- )
- )
+ ", ".join(steps_details)))
if total.proposed_definitions:
wrt("\nYou can implement step definitions for undefined steps with these snippets:\n\n")
@@ -118,14 +116,11 @@ def print_end(total):
wrt("def %s:\n" % method_name)
wrt(" assert False, 'This step must be implemented'\n")
+
def print_no_features_found(where):
where = core.fs.relpath(where)
if not where.startswith(os.sep):
where = '.%s%s' % (os.sep, where)
wrt('Oops!\n')
- wrt(
- 'could not find features at '
- '%s\n' % where
- )
-
+ wrt('could not find features at %s\n' % where)
View
6 lettuce/plugins/xunit_output.py
@@ -15,7 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import sys
from datetime import datetime
from lettuce.terrain import after
from lettuce.terrain import before
@@ -27,9 +26,11 @@ def wrt_output(filename, content):
f.write(content.encode('utf-8'))
f.close()
+
def total_seconds(td):
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
+
def enable(filename=None):
doc = minidom.Document()
@@ -51,7 +52,7 @@ def create_test_case(step):
if step.failed:
cdata = doc.createCDATASection(step.why.traceback)
failure = doc.createElement("failure")
- failure.setAttribute("message",step.why.cause)
+ failure.setAttribute("message", step.why.cause)
failure.appendChild(cdata)
tc.appendChild(failure)
@@ -63,4 +64,3 @@ def output_xml(total):
root.setAttribute("failed", str(total.steps_failed))
doc.appendChild(root)
wrt_output(output_filename, doc.toxml())
-
View
28 lettuce/strings.py
@@ -17,16 +17,17 @@
import re
import time
-import string
import unicodedata
+
def escape_if_necessary(what):
what = unicode(what)
if len(what) is 1:
what = u"[%s]" % what
return what
+
def get_stripped_lines(string, ignore_lines_starting_with=''):
string = unicode(string)
lines = [unicode(l.strip()) for l in string.splitlines()]
@@ -39,12 +40,13 @@ def get_stripped_lines(string, ignore_lines_starting_with=''):
return lines
+
def split_wisely(string, sep, strip=False):
string = unicode(string)
if strip:
- string=string.strip()
+ string = string.strip()
else:
- string=string.strip("\n")
+ string = string.strip("\n")
sep = unicode(sep)
regex = re.compile(escape_if_necessary(sep), re.UNICODE | re.M | re.I)
@@ -57,15 +59,18 @@ def split_wisely(string, sep, strip=False):
return [unicode(i) for i in items]
+
def wise_startswith(string, seed):
string = unicode(string).strip()
seed = unicode(seed)
regex = u"^%s" % re.escape(seed)
return bool(re.search(regex, string, re.I))
+
def remove_it(string, what):
return unicode(re.sub(unicode(what), "", unicode(string)).strip())
+
def column_width(string):
l = 0
for c in string:
@@ -75,6 +80,7 @@ def column_width(string):
l += 1
return l
+
def rfill(string, times, char=u" ", append=u""):
string = unicode(string)
missing = times - column_width(string)
@@ -83,13 +89,17 @@ def rfill(string, times, char=u" ", append=u""):
return unicode(string) + unicode(append)
+
def getlen(string):
return column_width(unicode(string)) + 1
+
def dicts_to_string(dicts, order):
escape = "#{%s}" % str(time.time())
+
def enline(line):
return unicode(line).replace("|", escape)
+
def deline(line):
return line.replace(escape, '\\|')
@@ -120,12 +130,16 @@ def deline(line):
return deline(u"\n".join(table) + u"\n")
+
def parse_hashes(lines):
escape = "#{%s}" % str(time.time())
+
def enline(line):
return unicode(line.replace("\\|", escape)).strip()
+
def deline(line):
return line.replace(escape, '|')
+
def discard_comments(lines):
return [line for line in lines if not line.startswith('#')]
@@ -146,6 +160,7 @@ def discard_comments(lines):
return keys, hashes
+
def parse_multiline(lines):
multilines = []
in_multiline = False
@@ -163,11 +178,11 @@ def parse_multiline(lines):
def extract_tags_from_line(given_line):
"""returns tags_array if given_line contains tags, else None"""
- line = string.rstrip(given_line)
+ line = given_line.rstrip()
tags = []
if re.match("\s*?\@", line):
tags = [tag for tag in re.split("\s*\@", line) if len(tag) > 0]
- if len(tags) == 0 or [tag for tag in tags if string.find(tag, " ") != -1]:
+ if len(tags) == 0 or any(' ' in tag for tag in tags):
return None
return tags
@@ -185,6 +200,7 @@ def consume_tags_lines(lines, tags):
else:
break
+
def consume_scenario(lines, scenario_prefix):
"""return string of scenario text
and reduce lines array by that much"""
@@ -205,6 +221,7 @@ def consume_scenario(lines, scenario_prefix):
scenario_lines.extend(get_lines_till_next_scenario(lines, scenario_prefix))
return unicode("\n".join(scenario_lines))
+
def get_lines_till_next_scenario(lines, scenario_prefix):
"""returns array of lines up till next scenario block"""
sep = unicode(scenario_prefix)
@@ -222,6 +239,7 @@ def get_lines_till_next_scenario(lines, scenario_prefix):
scenario_lines.append(lines.pop(0))
return scenario_lines
+
def split_scenarios(lines, scenario_prefix):
"""returns array of strings, one per scenario"""
scenario_strings = []
View
15 lettuce/terminal.py
@@ -18,6 +18,7 @@
import platform
import struct
+
def get_size():
if platform.system() == "Windows":
size = get_terminal_size_win()
@@ -29,6 +30,7 @@ def get_size():
return size
+
def get_terminal_size_win():
#Windows specific imports
from ctypes import windll, create_string_buffer
@@ -41,20 +43,21 @@ def get_terminal_size_win():
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
if res:
- import struct
- (bufx, bufy, curx, cury, wattr,
- left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
+ (bufx, bufy, curx, cury, wattr, left, top, right, bottom,
+ maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
sizex = right - left + 1
sizey = bottom - top + 1
- else:
- sizex, sizey = 80, 25 # can't determine actual size - return default values
+ else: # can't determine actual size - return default values
+ sizex, sizey = 80, 25
return sizex, sizey
def get_terminal_size_unix():
# Unix/Posix specific imports
- import fcntl, termios
+ import fcntl
+ import termios
+
def ioctl_GWINSZ(fd):
try:
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,

0 comments on commit 37d5a91

Please sign in to comment.
Something went wrong with that request. Please try again.