All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.expectit.ExpectImpl Maven / Gradle / Ivy

There is a newer version: 0.9.0
Show newest version
package net.sf.expectit;

/*
 * #%L
 * ExpectIt
 * %%
 * Copyright (C) 2014 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 net.sf.expectit.ExpectBuilder.validateDuration;
import static net.sf.expectit.Utils.toDebugString;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.expectit.interact.InteractBuilder;
import net.sf.expectit.matcher.Matcher;

/**
 * An implementation of the Expect interface which delegates actual work to SingleInputExpect
 * objects.
 */
class ExpectImpl extends AbstractExpectImpl {
    private static final Logger LOG = Logger.getLogger(ExpectImpl.class.getName());

    static final int INFINITE_TIMEOUT = -1; // value representing infinite timeout

    private final OutputStream output;
    private final SingleInputExpect[] inputs;
    private final Charset charset;
    private final Appendable echoOutput;
    @Deprecated
    private final boolean errorOnTimeout;
    private final ExecutorService executor;
    private final String lineSeparator;
    private final boolean exceptionOnFailure;
    private final boolean autoFlushEcho;

    ExpectImpl(
            final long timeout,
            final OutputStream output,
            final SingleInputExpect[] inputs,
            final Charset charset,
            final Appendable echoOutput,
            final boolean errorOnTimeoutOld,
            final String lineSeparator,
            final boolean exceptionOnFailure,
            final boolean autoFlushEcho) {
        super(timeout);
        this.output = output;
        this.inputs = inputs;
        this.charset = charset;
        this.echoOutput = echoOutput;
        this.errorOnTimeout = errorOnTimeoutOld;
        this.exceptionOnFailure = exceptionOnFailure;
        this.lineSeparator = lineSeparator;
        this.autoFlushEcho = autoFlushEcho;
        executor = Executors.newFixedThreadPool(
                inputs.length,
                new NamedExecutorThreadFactory("expect-"));
    }

    void start() {
        for (SingleInputExpect input : inputs) {
            input.start(executor);
        }
    }

    @Override
    public  R expectIn(int input, long timeoutMs, Matcher matcher)
            throws IOException {
        if (LOG.isLoggable(Level.FINE)) {
            LOG.fine(
                    String.format(
                            "Expect matcher '%s' with timeout %d (ms) in input #%d",
                            toDebugString(matcher),
                            timeoutMs,
                            input));
        }
        R result = inputs[input].expect(timeoutMs, matcher);
        if (exceptionOnFailure && !result.isSuccessful()) {
            final String inputBuffer = inputs[input].getBuffer().toString();
            throw new ExpectIOException(
                    "Expect operation fails (timeout: "
                            + timeoutMs + " ms) for matcher: " + matcher, inputBuffer);
        }
        if (errorOnTimeout && !result.isSuccessful()) {
            throw new AssertionError(
                    "Expect timeout (" + timeoutMs + " ms) for matcher: " + matcher);
        }
        return result;
    }

    @Override
    public Expect withTimeout(long duration, TimeUnit unit) {
        validateDuration(duration);
        return new ExpectTimeoutAdapter(this, unit.toMillis(duration));
    }

    @Override
    public Expect withInfiniteTimeout() {
        return new ExpectTimeoutAdapter(this, -1);
    }

    @Override
    public Expect send(String string) throws IOException {
        byte[] bytes = string.getBytes(charset);
        writeBytes(bytes);
        echoString(string);
        return this;
    }

    @Override
    public Expect sendLine() throws IOException {
        return sendLine("");
    }

    @Override
    public Expect sendLine(String string) throws IOException {
        return send(string + lineSeparator);
    }

    @Override
    public Expect sendBytes(byte[] bytes) throws IOException {
        writeBytes(bytes);
        echoString(new String(bytes, charset));
        return this;
    }

    private void writeBytes(byte[] bytes) throws IOException {
        if (LOG.isLoggable(Level.FINE)) {
            LOG.fine("Writing bytes: " + toDebugString(bytes, bytes.length, charset));
        }
        output.write(bytes);
        output.flush();
    }

    private void echoString(String string) throws IOException {
        if (echoOutput != null) {
            echoOutput.append(string);
            if (autoFlushEcho) {
                Utils.flushAppendable(echoOutput);
            }
        }
    }

    @Override
    public void close() throws IOException {
        for (SingleInputExpect input : inputs) {
            input.stop();
        }
        executor.shutdown();
        if (autoFlushEcho) {
            Utils.flushAppendable(echoOutput);
        }
    }

    @Override
    public InteractBuilder interact() {
        return interactWith(0);
    }

    @Override
    public InteractBuilder interactWith(final int input) {
        return interactWithInternal(this, input);
    }

    InteractBuilder interactWithInternal(final AbstractExpectImpl expect, final int input) {
        if (input >= inputs.length || input < 0) {
            throw new IllegalArgumentException("Input index is out of bounds: " + input);
        }
        return new InteractBuilderImpl(expect, input);
    }

    @Override
    SingleInputExpect[] getInputs() { return inputs; }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy