02
Jan

Steps to configure TypeRegistryConfigurer in cucumber

Implementing Custom Parameter types in cucumber:
==================================================


Cucumber Expressions can be extended so they automatically convert output parameters to your own types. Consider this Cucumber Expression:

I have a {color} ball

If we want the {color} output parameter to be converted to a Color object, we can define a custom parameter type in Cucumber's configuration.

typeRegistry.defineParameterType(new ParameterType<>(
    "color",           // name
    "red|blue|yellow", // regexp
    Color.class,       // type
    Color::new         // transformer function
))


The table below explains the various arguments you can pass when defining a parameter type.

Argument		Description
name			The name the parameter type will be recognised by in output parameters.
regexp			A regexp that will match the parameter. May include capture groups.
type			The return type of the transformer method.
transformer		A method that transforms the match from the regexp. Must have arity 1 if the regexp doesn't have any capture groups. Otherwise the arity must match the number of capture groups in regexp.
useForSnippets		Defaults to true. That means this parameter type will be used to generate snippets for undefined steps. If the regexp frequently matches text you don't intend to be used as arguments, disable its use for snippets with false.
preferForRegexpMatch	Defaults to false. Set to true if you have step definitions that use regular expressions, and you want this parameter type to take precedence over others during a match.



Complete example:
=====================

#1. Gherkin Step:
===================
	Given user gets random(3,true,true) parameter

#2. StepDefinition:
======================

	@Given("user gets {random} parameter")
	public void paramTest(RandomString randomString) {
	    System.out.println(randomString.string); 
	}


#3. Your custom class:
========================

RandomString class:

public class RandomString {

public String string;

public RandomString(String string) {
	    Matcher m = Pattern.compile("random\\((.?)\\)").matcher(string);
	    String t = "";
	    while (m.find()) {
	        t = m.group(1);
	    }
	    boolean isAlpha = true, isNum = true;
	    if (t.length() > 0) {
	        String[] placeholders = t.split(",");
	        if (placeholders.length == 3) {
	            int count = Integer.parseInt(placeholders[0]);
	            isAlpha = Boolean.valueOf(placeholders[1]);
	            isNum = Boolean.valueOf(placeholders[2]);
	            this.string = string.replaceAll("random(.*)", RandomStringUtils.random(count, isAlpha, isNum));
	        }
	    }
	    this.string = string.replaceAll("random(.*)", RandomStringUtils.random(3, isAlpha, isNum));
	}
}




#4. TypeRegistryImpl:
========================

public class TypeRegistryConfiguration implements TypeRegistryConfigurer {
    @Override
    public Locale locale() {
        return Locale.ENGLISH;
    }

    @Override
    public void configureTypeRegistry(TypeRegistry typeRegistry) {
        typeRegistry.defineParameterType(new ParameterType<>(
                "random",
                "random([0-9],true|false,true|false)",
                RandomString.class,
                RandomString::new)
        );
    }
}