Skip to content

Commit

Permalink
Added required attribute to ScenarioState.
Browse files Browse the repository at this point in the history
This commit adds a new boolean attribute "required" to both
ScenarioState and ExpectedScenarioState. If set to true on a
field within a stage, corresponding tests will fail automatically
if the state hasn't been provided.

fixes TNG#255
  • Loading branch information
Airblader committed Dec 21, 2016
1 parent e54f826 commit fc3ba73
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
@Target( ElementType.FIELD )
public @interface ExpectedScenarioState {
Resolution resolution() default Resolution.AUTO;

/**
* Defines whether this state is required.
* If set to {@code true} and no stage provided this state, the tests will automatically fail.
*/
boolean required() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
public enum Resolution {
TYPE, NAME, AUTO;
}

/**
* Defines whether this state is required.
* If set to {@code true} and no stage provided this state, the tests will automatically fail.
*/
boolean required() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ public void updateValues( Object object ) {
if( value != null ) {
field.set( object, value );
log.debug( "Setting field {} to value {}", field, value );
} else if( isRequired( field ) ) {
throw new RuntimeException( "TODO Better exception?" );
}
} catch( IllegalAccessException e ) {
throw new RuntimeException( "Error while updating field " + field, e );
Expand All @@ -107,23 +109,19 @@ public <T> void injectValueByName( String name, T value ) {

private void updateValue( Field field, Object value ) {
Resolution resolution = getResolution( field );
Class<?> type = field.getType();
if( resolution == Resolution.NAME ) {
String name = field.getName();
state.updateValueByName( name, value );
state.updateValueByName( field.getName(), value );
} else {
state.updateValueByType( type, value );
state.updateValueByType( field.getType(), value );
}
}

private Object getValue( Field field ) {
Resolution resolution = getResolution( field );
Class<?> type = field.getType();
if( resolution == Resolution.NAME ) {
String name = field.getName();
return state.getValueByName( name );
return state.getValueByName( field.getName() );
}
return state.getValueByType( type );
return state.getValueByType( field.getType() );
}

private Resolution getResolution( Field field ) {
Expand All @@ -146,9 +144,23 @@ private Resolution getDeclaredResolution( Field field ) {
return ( (ExpectedScenarioState) annotation ).resolution();
}
}

throw new IllegalArgumentException( "Field " + field + " has no valid annotation" );
}

private boolean isRequired( Field field ) {
for( Annotation annotation : field.getAnnotations() ) {
if( annotation instanceof ScenarioState ) {
return ( (ScenarioState) annotation ).required();
}
if( annotation instanceof ExpectedScenarioState ) {
return ( (ExpectedScenarioState) annotation ).required();
}
}

return false;
}

private boolean typeIsTooGeneric( Class<?> type ) {
return type.isPrimitive()
|| type.getName().startsWith( "java.lang" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,17 @@ public void abstract_steps_should_appear_in_the_report_model() throws Throwable

}

static class StageWithMissingState {
@ScenarioState( required = true )
Boolean willNotBeProvided;

public void something() {}
}

@Test( expected = RuntimeException.class )
public void required_states_must_be_present() throws Throwable {
StageWithMissingState stage = addStage( StageWithMissingState.class );
stage.something();
}

}

0 comments on commit fc3ba73

Please sign in to comment.