package rabbitescape.engine.solution;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.*;
import rabbitescape.engine.Token;
import rabbitescape.engine.World;
import static org.junit.Assert.fail;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*;
public class TestSolutionParser
{
@Test
public void Empty_string_gives_single_empty_command()
{
assertThat(
SolutionParser.parse( "" ),
equalTo(
new Solution( new SolutionCommand() )
)
);
}
@Test
public void Single_status_gives_single_validation_action()
{
assertThat(
SolutionParser.parse( "WON" ),
equalTo(
new Solution(
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) )
)
)
);
}
@Test
public void Trailing_semicolon_means_empty_command_at_end()
{
assertThat(
SolutionParser.parse( "WON;" ),
equalTo(
new Solution(
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) ),
new SolutionCommand()
)
)
);
}
@Test
public void Leading_semicolon_means_empty_command_at_start()
{
assertThat(
SolutionParser.parse( ";WON" ),
equalTo(
new Solution(
new SolutionCommand(),
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) )
)
)
);
}
@Test
public void Lots_of_empty_commands_preserved()
{
assertThat(
SolutionParser.parse( ";;;WON;;;" ),
equalTo(
new Solution(
new SolutionCommand(),
new SolutionCommand(),
new SolutionCommand(),
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) ),
new SolutionCommand(),
new SolutionCommand(),
new SolutionCommand()
)
)
);
}
@Test
public void Multiple_actions_are_found_and_listed()
{
assertThat(
SolutionParser.parse( "1;2;WON" ),
equalTo(
new Solution(
new SolutionCommand( new WaitAction( 1 ) ),
new SolutionCommand( new WaitAction( 2 ) ),
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) )
)
)
);
}
@Test
public void Simultaneous_actions_are_noted()
{
assertThat(
SolutionParser.parse( "bash&(1,1);WON" ),
equalTo(
new Solution(
new SolutionCommand(
new SelectAction( Token.Type.bash ),
new PlaceTokenAction( 1, 1 ) ),
new SolutionCommand(
new AssertStateAction( World.CompletionState.WON ) )
)
)
);
}
@Test
public void Nonwait_actions_dont_get_a_wait_appended()
{
assertThat(
SolutionParser.parse( "bridge;LOST" ),
equalTo(
new Solution(
new SolutionCommand(
new SelectAction( Token.Type.bridge )
),
new SolutionCommand(
new AssertStateAction( World.CompletionState.LOST ) )
)
)
);
}
@Test
public void Empty_commands_dont_get_a_wait_appended()
{
assertThat(
SolutionParser.parse( ";;" ),
equalTo(
new Solution(
new SolutionCommand(),
new SolutionCommand(),
new SolutionCommand()
)
)
);
}
@Test
public void No_assert_added_at_end()
{
assertThat(
SolutionParser.parse( "bridge;(22,40)" ),
equalTo(
new Solution(
new SolutionCommand(
new SelectAction( Token.Type.bridge )
),
new SolutionCommand(
new PlaceTokenAction( 22, 40 )
)
)
)
);
}
@Test
public void Can_parse_single_action()
{
assertThat(
SolutionParser.parseCommand( "bash" ),
equalTo(
new SolutionCommand(
new SelectAction( Token.Type.bash ) )
)
);
}
@Test
public void Can_parse_multiple_single_actions()
{
assertThat(
SolutionParser.parseCommand( "bash&(1,2)" ),
equalTo(
new SolutionCommand(
new SelectAction( Token.Type.bash )
, new PlaceTokenAction( 1, 2 )
)
)
);
}
@Test
public void Unrecognised_ability_is_an_error()
{
try
{
SolutionParser.parse( "unknown_ability" );
fail( "Expected an InvalidAction!" );
}
catch ( InvalidAction e )
{
assertThat( e.action, equalTo( "unknown_ability" ) );
}
}
@Test
public void Unrecognised_state_is_an_error()
{
try
{
SolutionParser.parse( "1;UNKNOWN_STATE" );
fail( "Expected an InvalidAction!" );
}
catch ( InvalidAction e )
{
assertThat( e.action, equalTo( "UNKNOWN_STATE" ) );
}
}
@Test
public void Nonnumeric_position_is_an_error()
{
try
{
SolutionParser.parse( "bash;(3,a)" );
fail( "Expected an InvalidAction!" );
}
catch ( InvalidAction e )
{
assertThat( e.action, equalTo( "(3,a)" ) );
}
}
@Test
public void Massive_wait_is_an_error()
{
String bigNum = String.valueOf( Long.MAX_VALUE );
try
{
SolutionParser.parse( bigNum );
fail( "Expected an InvalidAction!" );
}
catch ( InvalidAction e )
{
assertThat( e.action, equalTo( bigNum ) );
}
}
@Test
public void Massive_position_is_an_error()
{
String bigNum = String.valueOf( Long.MAX_VALUE );
try
{
SolutionParser.parse( "bash;(3," + bigNum + ")" );
fail( "Expected an InvalidAction!" );
}
catch ( InvalidAction e )
{
assertThat( e.action, equalTo( "(3," + bigNum + ")" ) );
}
}
@Test
public void Empty_string_round_trips()
{
assertThat( "", roundTrips() );
}
@Test
public void Wait_then_empty_round_trips()
{
assertThat( "2;", roundTrips() );
}
@Test
public void Two_waits_then_empty_round_trips()
{
assertThat( "5;6;", roundTrips() );
}
@Test
public void Empty_at_start_round_trips()
{
assertThat( ";5;6;", roundTrips() );
}
@Test
public void Single_choose_token_round_trips()
{
assertThat( "bash", roundTrips() );
}
@Test
public void Single_assert_round_trips()
{
assertThat( "WON", roundTrips() );
}
@Test
public void Two_normal_commands_round_trips()
{
assertThat( "bash;(3,2)", roundTrips() );
}
@Test
public void Two_normal_actions_round_trips()
{
assertThat( "bash&(3,2)", roundTrips() );
}
@Test
public void Multiple_actions_and_commands_round_trips()
{
assertThat( ";bash&(3,2);RUNNING;3;bash", roundTrips() );
}
@Test
public void Leading_and_trailing_empty_actions()
{
assertThat( ";;;2;bash&(3,2);RUNNING;3;bash;;;", roundTrips() );
}
@Test
public void Single_choose_token_plus_empty_round_trips()
{
assertThat( "bash;", roundTrips() );
}
@Test
public void Single_wait_round_trips()
{
assertThat( "", roundTrips() );
}
@Test
public void Wait_1_changes_to_blank()
{
assertThat(
SolutionParser.serialise( SolutionParser.parse( "1" ) ),
equalTo( "" )
);
}
@Test
public void Two_waits_round_trip()
{
assertThat( "5;6", roundTrips() );
}
@Test
public void Until_WON_round_trips()
{
assertThat( "5;6;until:WON", roundTrips() );
}
@Test
public void Until_LOST_round_trips()
{
assertThat( "dig&(7,4);until:LOST", roundTrips() );
}
@Test( expected=SolutionCommand.WaitActionInMultiActionCommand.class )
public void Multi_action_commands_must_not_include_a_wait()
{
SolutionParser.parse( "2&bash");
}
// ---
private Matcher<String> roundTrips()
{
return new BaseMatcher<String>()
{
private String after = null;
@Override
public void describeTo( Description desc )
{
desc.appendText( "\"" + after + "\"" );
}
@Override
public boolean matches( Object inputObj )
{
if ( !( inputObj instanceof String ) )
{
return false;
}
String before = (String)inputObj;
after = SolutionParser.serialise(
SolutionParser.parse( before ) );
return after.equals( before );
}
};
}
}