PY-30563, PY-30768: Support parameter types for behave and pytest-bdd

There are 2 parsers:
* (cf)parse: supports syntax like {paramName:d} or custom types: {paramName:Foo}. Foo must be mapped to real type by behave and pytest-bdd using different approaches.
* re: supports regexp. By default types are strings, but pytest-bdd can match param names to certain types.

And there are 2 frameworks (each of them supports both parsers):
* behave
* pytest-bdd

Parsers are implemented as PyBDDParser inheritors (and called *processors for historical reasons) and by PyBDDMatcher instances.

Frameworks are implemented by PyStepDefinition inheritors.

PyStepDefinition's know to how to:
* fetch type-alias-to-type or argument-name-to-type mappings
* find step definition expression in decorator

Parsers know how to:
* convert step definition to python regexp
* get argument types using information from PyStepDefinition's
This commit is contained in:
Ilya.Kazakevich
2018-07-06 23:27:16 +03:00
parent 91569e4aa5
commit 4039d32479
@@ -60,6 +60,11 @@ public class PyEvaluator {
*/
private boolean myEnableResolve = true;
/**
* Store expressions as values if they can't be evaludated
*/
private boolean myAllowExpressionsAsValues = false;
public void setNamespace(@Nullable Map<String, Object> namespace) {
myNamespace = namespace;
}
@@ -68,6 +73,10 @@ public class PyEvaluator {
myEvaluateCollectionItems = evaluateCollectionItems;
}
public void setAllowExpressionsAsValues(final boolean allowExpressionsAsValues) {
myAllowExpressionsAsValues = allowExpressionsAsValues;
}
public void setEvaluateKeys(boolean evaluateKeys) {
myEvaluateKeys = evaluateKeys;
}
@@ -304,13 +313,34 @@ public class PyEvaluator {
}
return result;
}
}
final PyExpression[] arguments = expression.getArguments();
//dict(foo="spam")
if (arguments.length > 0) {
final Map<Object, Object> result = new HashMap<>();
for (final PyExpression argument : arguments) {
if (!(argument instanceof PyKeywordArgument)) {
continue;
}
final PyKeywordArgument keywordArgument = (PyKeywordArgument)argument;
final String keyword = keywordArgument.getKeyword();
if (keyword == null) {
continue;
}
addRecordFromDict(result, keyword, keywordArgument.getValueExpression());
}
return result;
}
}
return null;
}
private void addRecordFromDict(@NotNull Map<Object, Object> result, @NotNull PyExpression key, @Nullable PyExpression value) {
result.put(myEvaluateKeys ? evaluate(key) : key, myEvaluateCollectionItems ? evaluate(value) : value);
result.put(myEvaluateKeys ? evaluate(key) : key, myEvaluateCollectionItems ? evaluateOrGet(value) : value);
}
private void addRecordFromDict(@NotNull Map<Object, Object> result, @NotNull String key, @Nullable PyExpression value) {
result.put(key, myEvaluateCollectionItems ? evaluateOrGet(value) : value);
}
@NotNull
@@ -430,4 +460,13 @@ public class PyEvaluator {
return null;
}
@Nullable
private Object evaluateOrGet(@Nullable final PyExpression expression) {
final Object result = evaluate(expression);
if (result !=null) {
return result;
}
return myAllowExpressionsAsValues ? expression : null;
}
}