OutcomesTable.java
- package org.jbehave.core.model;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- 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;
- /**
- * Represents a tabular structure that holds {@link Outcome}s to be verified by invoking method {@link #verify()}. If
- * verification fails an {@link OutcomesFailed} exception is thrown.
- * <p>The Outcomes Tables allows the specification of {@link Keywords} for the outcome fields, as well as rendering
- * formats for different types. The default formats include:
- * <ul>
- * <li>Date: "EEE MMM dd hh:mm:ss zzz yyyy"</li>
- * <li>Number: "0.###"</li>
- * <li>Boolean: "yes,no"</li>
- * </ul>
- * These formats can be overridden as well as new ones added. The formats can be retrieved via methods
- * {@link #getFormat(Type)} and {@link #getFormat(String)}.</p>
- */
- public class OutcomesTable {
- private static final String NEWLINE = "\n";
- private static final String HEADER_SEPARATOR = "|";
- private static final String VALUE_SEPARATOR = "|";
- private final Keywords keywords;
- private final Map<Type,String> formats;
- private final List<Outcome<?>> outcomes = new ArrayList<>();
- private final List<Outcome<?>> failedOutcomes = new ArrayList<>();
- private UUIDExceptionWrapper failureCause;
- public OutcomesTable() {
- this(new LocalizedKeywords());
- }
- public OutcomesTable(Keywords keywords) {
- this(keywords, defaultFormats());
- }
- public OutcomesTable(Map<Type, String> formats) {
- this(new LocalizedKeywords(), formats);
- }
- public OutcomesTable(Keywords keywords, Map<Type, String> formats) {
- this.keywords = keywords;
- this.formats = mergeWithDefaults(formats);
- }
- /**
- * Creates outcomes table using the specified keywords and date format
- *
- * @deprecated Use {@link #OutcomesTable(Keywords, Map)}
- */
- @Deprecated
- public OutcomesTable(Keywords keywords, String dateFormat) {
- this(keywords, mergeWithDefaults(Date.class, dateFormat));
- }
- public <T> void addOutcome(String description, T value, Matcher<T> matcher) {
- outcomes.add(new Outcome<>(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 Map<Type, String> getFormats() {
- return formats;
- }
- public String getFormat(Type type) {
- return formats.get(type);
- }
- public String getFormat(String typeName) {
- try {
- return getFormat(Class.forName(typeName));
- } catch (ClassNotFoundException e) {
- throw new FormatTypeInvalid(typeName, e);
- }
- }
- /**
- * Provides used date format
- *
- * @deprecated Use {@link #getFormat(Type)}
- */
- @Deprecated
- public String getDateFormat() {
- return getFormat(Date.class);
- }
- 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);
- }
- private static Map<Type,String> defaultFormats() {
- Map<Type,String> map = new HashMap<>();
- map.put(Date.class, "EEE MMM dd hh:mm:ss zzz yyyy");
- map.put(Number.class, "0.###");
- map.put(Boolean.class, "yes,no");
- return map;
- }
- private static Map<Type,String> mergeWithDefaults(Type type, String format) {
- Map<Type,String> map = defaultFormats();
- map.put(type, format);
- return map;
- }
- private Map<Type, String> mergeWithDefaults(Map<Type, String> formats) {
- Map<Type,String> map = defaultFormats();
- map.putAll(formats);
- return map;
- }
- 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;
- }
- }
- public static class FormatTypeInvalid extends RuntimeException {
- public FormatTypeInvalid(String type, Throwable e) {
- super(type, e);
- }
- }
- }