Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lettuce
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
lettuce
Commits
4b5db1bb
Commit
4b5db1bb
authored
Jun 13, 2012
by
Gabriel Falcao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
just some brainstorming
parent
87d8afbf
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
161 additions
and
6 deletions
+161
-6
TODO.md
+7
-0
lettuce/__init__.py
+1
-1
lettuce/core.py
+15
-2
lettuce/decorators.py
+40
-2
lettuce/exceptions.py
+5
-0
lettuce/registry.py
+2
-1
tests/unit/test_step_transformations.py
+91
-0
No files found.
TODO.md
0 → 100644
View file @
4b5db1bb
before 0.2.0:
*
https://github.com/gabrielfalcao/lettuce/pull/224
*
https://github.com/gabrielfalcao/lettuce/pull/255
*
https://github.com/gabrielfalcao/lettuce/pull/256
*
all the "high-priority" labeled tickets
*
https://github.com/gabrielfalcao/lettuce/issues/103 (maybe)
*
https://github.com/gabrielfalcao/lettuce/issues/198
lettuce/__init__.py
View file @
4b5db1bb
...
...
@@ -31,7 +31,7 @@ from lettuce.terrain import world
from
lettuce.decorators
import
step
from
lettuce.registry
import
call_hook
from
lettuce.registry
import
STEP_REGISTRY
from
lettuce.registry
import
STEP_REGISTRY
,
CASTER_REGISTRY
from
lettuce.registry
import
CALLBACK_REGISTRY
from
lettuce.exceptions
import
StepLoadingError
from
lettuce.plugins
import
xunit_output
...
...
lettuce/core.py
View file @
4b5db1bb
...
...
@@ -24,7 +24,7 @@ from copy import deepcopy
from
lettuce
import
strings
from
lettuce
import
languages
from
lettuce.fs
import
FileSystem
from
lettuce.registry
import
STEP_REGISTRY
from
lettuce.registry
import
STEP_REGISTRY
,
CASTER_REGISTRY
from
lettuce.registry
import
call_hook
from
lettuce.exceptions
import
ReasonToFail
from
lettuce.exceptions
import
NoDefinitionFound
...
...
@@ -110,16 +110,29 @@ 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"""
def
__init__
(
self
,
step
,
function
):
self
.
step
=
step
self
.
function
=
function
self
.
file
=
fs
.
relpath
(
function
.
func_code
.
co_filename
)
self
.
line
=
function
.
func_code
.
co_firstlineno
+
1
self
.
step
=
step
def
_apply_casters
(
self
,
step
,
args
):
sentence
=
step
.
sentence
if
not
args
:
return
()
for
regex
,
caster
in
CASTER_REGISTRY
.
items
():
matched
=
re
.
search
(
regex
,
sentence
)
if
matched
:
args
=
(
caster
(
*
args
),
)
return
args
def
__call__
(
self
,
*
args
,
**
kw
):
"""Method that actually wrapps the call to step definition
callback. Sends step object as first argument
"""
try
:
args
=
self
.
_apply_casters
(
self
.
step
,
args
)
ret
=
self
.
function
(
self
.
step
,
*
args
,
**
kw
)
self
.
step
.
passed
=
True
except
Exception
,
e
:
...
...
lettuce/decorators.py
View file @
4b5db1bb
...
...
@@ -15,8 +15,43 @@
# 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
re
from
lettuce.core
import
STEP_REGISTRY
from
lettuce.exceptions
import
StepLoadingError
from
lettuce.core
import
STEP_REGISTRY
,
CASTER_REGISTRY
from
lettuce.exceptions
import
CasterLoadingError
,
StepLoadingError
def
caster
(
regex
):
"""Decorates a function that will be responsible for casting
matched regex into object, leveraging more flexibility on step
definitions and simplifying the test ecosystem.
Example::
>>> from lettuce import step
>>> from models import Contact
>>>
>>> @step.caster(r'the person "(.*)"')
... def into_a_contact_object(value):
... return Contact.objects.get(name=value)
...
>>> @step(r'Given the person "(.*)" is erased from my address book')
... def given_i_do_something(step, user):
... user.delete()
Notice the name matched in the regex below being cast into a
`Contact` object
"""
def
wrap
(
func
):
try
:
re
.
compile
(
regex
)
except
re
.
error
,
e
:
raise
CasterLoadingError
(
"Error when trying to compile:
\n
"
" regex:
%
r
\n
"
" for function:
%
s
\n
"
" error:
%
s"
%
(
regex
,
func
,
e
))
CASTER_REGISTRY
[
regex
]
=
func
return
func
return
wrap
def
step
(
regex
):
...
...
@@ -36,6 +71,7 @@ def step(regex):
Notice that all step definitions take a step object as argument.
"""
def
wrap
(
func
):
try
:
re
.
compile
(
regex
)
...
...
@@ -48,3 +84,5 @@ def step(regex):
return
func
return
wrap
step
.
caster
=
caster
lettuce/exceptions.py
View file @
4b5db1bb
...
...
@@ -50,3 +50,8 @@ class LettuceSyntaxError(SyntaxError):
class
StepLoadingError
(
Exception
):
"""Raised when a step cannot be loaded."""
pass
class
CasterLoadingError
(
Exception
):
"""Raised when a caster's regex cannot be compiled."""
pass
lettuce/registry.py
View file @
4b5db1bb
...
...
@@ -38,8 +38,8 @@ class CallbackDict(dict):
for
callback_list
in
action_dict
.
values
():
callback_list
[:]
=
[]
STEP_REGISTRY
=
{}
CASTER_REGISTRY
=
{}
CALLBACK_REGISTRY
=
CallbackDict
(
{
'all'
:
{
...
...
@@ -91,4 +91,5 @@ def call_hook(situation, kind, *args, **kw):
def
clear
():
STEP_REGISTRY
.
clear
()
CASTER_REGISTRY
.
clear
()
CALLBACK_REGISTRY
.
clear
()
tests/unit/test_step_transformations.py
0 → 100644
View file @
4b5db1bb
# -*- coding: utf-8 -*-
# <Lettuce - Behaviour Driven Development for python>
# Copyright (C) <2010-2012> Gabriel Falcão <gabriel@nacaolivre.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# 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
lettuce
import
step
,
world
,
Feature
from
sure
import
that
,
scenario
FEATURE1
=
'''
Feature: Transformations
Scenario: Simple matching
Given the following users:
| name | email |
| Gabriel | gabriel@lettuce.it |
| Lincoln | lincoln@comum.org |
When the user "Gabriel" is mentioned
Then it becomes available in `world` as "last_user"
And it is an `User` instance
'''
THIS_MODULE
=
sys
.
modules
[
__name__
]
def
step_runner_environ
(
context
):
"Make sure the test environment is what is expected"
from
lettuce
import
registry
registry
.
clear
()
world
.
users
=
{}
class
User
:
def
__init__
(
self
,
name
,
email
):
self
.
name
=
name
self
.
email
=
email
def
save
(
self
):
world
.
users
[
self
.
name
]
=
self
@step
(
'Given the following users'
)
def
collect_users
(
step
):
for
data
in
step
.
hashes
:
user
=
User
(
**
data
)
user
.
save
()
@step
(
r'When the user "(\w+)" is mentioned'
)
def
mention_user
(
step
,
user
):
world
.
last_user
=
user
@step
(
r'Then it becomes available.* as "([\w_]+)"'
)
def
becomes_available
(
step
,
attribute
):
assert
(
hasattr
(
world
,
attribute
),
'world should contain the attribute
%
s'
%
attribute
)
@step
(
r'And it is an `(\w+)` instance'
)
def
and_is_instance_of
(
step
,
klass
):
import
ipdb
;
ipdb
.
set_trace
()
assert
that
(
world
.
last_user
)
.
is_a
(
klass
)
@scenario
(
step_runner_environ
)
def
test_transformations
(
context
):
@step.caster
(
r'the user "(\w+)" is mentioned'
)
def
capture_users_by_name
(
name
):
return
world
.
users
[
name
]
@step.caster
(
r'it is an `(\w+)`'
)
def
get_class_by_name
(
name
):
return
THIS_MODULE
[
name
]
f
=
Feature
.
from_string
(
FEATURE1
)
feature_result
=
f
.
run
()
scenario_result
=
feature_result
.
scenario_results
[
0
]
assert
that
(
scenario_result
.
steps_undefined
)
.
equals
([])
assert
that
(
scenario_result
.
steps_failed
)
.
equals
([])
assert
feature_result
.
passed
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment