package net.sf.expectit.interact; /* * #%L * ExpectIt * %% * Copyright (C) 2014 - 2015 Alexey Gavrilov and contributors * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import static junit.framework.Assert.assertTrue; import static junit.framework.Assert.fail; import static net.sf.expectit.TestUtils.SMALL_TIMEOUT; import static net.sf.expectit.TestUtils.mockInputStream; import static net.sf.expectit.matcher.Matchers.allOf; import static net.sf.expectit.matcher.Matchers.anyOf; import static net.sf.expectit.matcher.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import net.sf.expectit.Expect; import net.sf.expectit.ExpectBuilder; import net.sf.expectit.MockInputStream; import net.sf.expectit.MultiResult; import net.sf.expectit.Result; import org.junit.After; import org.junit.Assert; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; public class InteractTest { private Expect expect; @After public void cleanup() throws IOException { if (expect != null) { expect.close(); } } @Test public void simpleTest() throws Exception { final MockInputStream input = mockInputStream("AaBbAaBbcdefF"); expect = new ExpectBuilder() .withExceptionOnFailure() .withTimeout(SMALL_TIMEOUT, TimeUnit.MILLISECONDS) .withInputs(input.getStream()) .build(); input.waitUntilReady(); final Action<Result> action1 = mock(Action.class); final Action<MultiResult> action2 = mock(Action.class); final Action<Result> action3 = mock(Action.class); final ArgumentCaptor<Result> result1 = ArgumentCaptor.forClass(Result.class); final ArgumentCaptor<MultiResult> result2 = ArgumentCaptor.forClass(MultiResult.class); final ArgumentCaptor<Result> result3 = ArgumentCaptor.forClass(Result.class); doNothing().when(action1).apply(result1.capture()); doNothing().when(action2).apply(result2.capture()); doNothing().when(action3).apply(result3.capture()); final Result result = expect.interact() .when(contains("a")).then(action1) .when(allOf(contains("b"))).then(action2) .when(contains("XXX")).then(action3) .until(contains("ef")); assertEquals(result.getBefore(), "cd"); assertEquals(result1.getValue().getBefore(), "A"); assertEquals(result2.getValue().getBefore(), "AaB"); verify(action1, Mockito.times(2)).apply(any(Result.class)); verify(action2, Mockito.times(2)).apply(any(MultiResult.class)); verifyNoMoreInteractions(action3); } @Test (timeout = 1000) public void negativeTest() throws Exception { final MockInputStream input = mockInputStream("abcd"); expect = new ExpectBuilder() .withInfiniteTimeout() .withInputs(input.getStream()) .build(); input.waitUntilReady(); final Action<Result> action1 = mock(Action.class); final Result result = expect .withTimeout(SMALL_TIMEOUT, TimeUnit.MILLISECONDS) .interact() .when(contains("X")).then(action1) .until(contains("Y")); assertFalse(result.isSuccessful()); assertEquals(result.getInput(), "abcd"); verifyNoMoreInteractions(action1); } @Test public void testException() throws Exception { expect = new ExpectBuilder() .withInputs(mock(InputStream.class)) .build(); try { expect.interactWith(1); Assert.fail(); } catch (IllegalArgumentException ignore) { } try { expect.interactWith(-1); Assert.fail(); } catch (IllegalArgumentException ignore) { } try { expect.interact().when(contains("X")).then(null); fail(); } catch (NullPointerException ignore) { } } @Test public void testCornerCases() throws Exception { final MockInputStream input = mockInputStream("xyz"); final MockInputStream input2 = mockInputStream("abcd"); expect = new ExpectBuilder() .withTimeout(SMALL_TIMEOUT, TimeUnit.MILLISECONDS) .withExceptionOnFailure() .withInputs(input.getStream(), input2.getStream()) .build(); input.waitUntilReady(); input2.waitUntilReady(); final Result result = expect.interactWith(1).until(contains("ab")); assertTrue(result.isSuccessful()); final Action<Result> action = mock(Action.class); final Result r = expect.interact().when(contains("y")).then(action).until(contains("x")); assertTrue(r.isSuccessful()); verifyNoMoreInteractions(action); } @Test public void testRealWorld() throws Exception { final MockInputStream input = mockInputStream("password"); expect = new ExpectBuilder() .withTimeout(SMALL_TIMEOUT, TimeUnit.MILLISECONDS) .withExceptionOnFailure() .withInputs(input.getStream()) .build(); input.waitUntilReady(); final Action<Result> action1 = new Action<Result>() { @Override public void apply(final Result result) { try { input.push("exit"); } catch (final InterruptedException e) { throw new IllegalStateException(e); } } }; final Action<Result> action2 = new Action<Result>() { @Override public void apply(final Result result) { try { input.push("#"); } catch (final InterruptedException e) { throw new IllegalStateException(e); } } }; expect.interact() .when(contains("#")).then(action1) .when(contains("assword")).then(action2) .until(contains("exit")); } }