package org.jbehave.core.model; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.hamcrest.Matcher; import org.jbehave.core.configuration.Keywords; import org.jbehave.core.failures.UUIDExceptionWrapper; import org.jbehave.core.i18n.LocalizedKeywords; public class OutcomesTable { private static final String NEWLINE = "\n"; private static final String HEADER_SEPARATOR = "|"; private static final String VALUE_SEPARATOR = "|"; private static final String DEFAULT_DATE_FORMAT = "EEE MMM dd hh:mm:ss zzz yyyy"; private final Keywords keywords; private final String dateFormat; private final List<Outcome<?>> outcomes = new ArrayList<Outcome<?>>(); private final List<Outcome<?>> failedOutcomes = new ArrayList<Outcome<?>>(); private UUIDExceptionWrapper failureCause; public OutcomesTable() { this(new LocalizedKeywords()); } public OutcomesTable(Keywords keywords) { this(keywords, DEFAULT_DATE_FORMAT); } public OutcomesTable(Keywords keywords, String dateFormat) { this.keywords = keywords; this.dateFormat = dateFormat; } public <T> void addOutcome(String description, T value, Matcher<T> matcher) { outcomes.add(new Outcome<T>(description, value, matcher)); } public void verify() { boolean failed = false; failedOutcomes.clear(); for (Outcome<?> outcome : outcomes) { if (!outcome.isVerified()) { failedOutcomes.add(outcome); failed = true; break; } } if (failed) { failureCause = new UUIDExceptionWrapper(new OutcomesFailed(this)); throw failureCause; } } public UUIDExceptionWrapper failureCause() { return failureCause; } public List<Outcome<?>> getOutcomes() { return outcomes; } public List<Outcome<?>> getFailedOutcomes() { return failedOutcomes; } public List<String> getOutcomeFields() { return keywords.outcomeFields(); } public String getDateFormat(){ return dateFormat; } public String asString() { StringBuilder sb = new StringBuilder(); for (Iterator<String> iterator = getOutcomeFields().iterator(); iterator.hasNext();) { sb.append(HEADER_SEPARATOR).append(iterator.next()); if (!iterator.hasNext()) { sb.append(HEADER_SEPARATOR).append(NEWLINE); } } for (Outcome<?> outcome : outcomes) { sb.append(VALUE_SEPARATOR).append(outcome.getDescription()).append(VALUE_SEPARATOR).append( outcome.getValue()).append(VALUE_SEPARATOR).append(outcome.getMatcher()).append(VALUE_SEPARATOR) .append(outcome.isVerified()).append(VALUE_SEPARATOR).append(NEWLINE); } return sb.toString(); } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } public static class Outcome<T> { private final String description; private final T value; private final Matcher<T> matcher; private final boolean verified; public Outcome(String description, T value, Matcher<T> matcher) { this.description = description; this.value = value; this.matcher = matcher; this.verified = matcher.matches(value); } public String getDescription() { return description; } public T getValue() { return value; } public Matcher<T> getMatcher() { return matcher; } public boolean isVerified() { return verified; } @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } @SuppressWarnings("serial") public static class OutcomesFailed extends UUIDExceptionWrapper { private transient OutcomesTable outcomes; public OutcomesFailed(OutcomesTable outcomes) { this.outcomes = outcomes; } public OutcomesTable outcomesTable() { return outcomes; } } }