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

net.thucydides.core.model.DataTable Maven / Gradle / Ivy

There is a newer version: 4.2.1
Show newest version
package net.thucydides.core.model;

import ch.lambdaj.function.convert.Converter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import static ch.lambdaj.Lambda.convert;

/**
 * A table of test data
 */
public class DataTable {
    private final List headers;
    private final List rows;
    private final boolean predefinedRows;
    private AtomicInteger currentRow = new AtomicInteger(0);
    private List dataSetDescriptors;

    private final static List NO_ROWS = Lists.newArrayList();

    protected DataTable(List headers, List rows) {
        this(headers, new CopyOnWriteArrayList(rows), null, null, ImmutableList.of(DataSetDescriptor.DEFAULT_DESCRIPTOR));
    }

    protected DataTable(List headers, List rows, String title, String description) {
        this(headers, new CopyOnWriteArrayList(rows), title, description, ImmutableList.of(new DataSetDescriptor(0,0,title, description)));
    }

    protected DataTable(List headers, List rows, String title, String description, List dataSetDescriptors) {
        this.headers = headers;
        this.rows = new CopyOnWriteArrayList(rows);
        this.predefinedRows = !rows.isEmpty();
        this.dataSetDescriptors = dataSetDescriptors;
        if ((title != null) || (description != null)) {
            setLatestNameAndDescription(title, description);
        }
    }

    public static DataTableBuilder withHeaders(List headers) {
        return new DataTableBuilder(headers);
    }

    public List getHeaders() {
        return ImmutableList.copyOf(headers);
    }

    public List getRows() {
        return ImmutableList.copyOf(rows);
    }

    public RowValueAccessor row(int rowNumber) {
        return new RowValueAccessor(this, rowNumber);
    }

    public RowValueAccessor nextRow() {
        return new RowValueAccessor(this, nextRowNumber());
    }

    public boolean atLastRow() {
        return ((rows.isEmpty()) || (currentRow.get() == rows.size() - 1));
    }

    public RowValueAccessor currentRow() {
        return new RowValueAccessor(this, currentRowNumber());
    }

    private int nextRowNumber() {
        return currentRow.incrementAndGet();
    }

    private int currentRowNumber() {
        return currentRow.intValue();
    }

    public void addRow(Map data) {
        addRow(new DataTableRow(ImmutableList.copyOf(data.values())));
    }

    public List getDataSetDescriptors() {
        return dataSetDescriptors;
    }

    public void addRow(DataTableRow dataTableRow) {
        appendRow(dataTableRow);
        currentRow.set(rows.size() - 1);
    }

    public void appendRow(Map data) {
        appendRow(new DataTableRow(ImmutableList.copyOf(data.values())));
    }

    public void appendRow(DataTableRow dataTableRow) {
        rows.add(dataTableRow);
    }

    public void addRows(List rows) {
        for (DataTableRow row : rows) {
            DataTableRow newRow = new DataTableRow(ImmutableList.copyOf(row.getValues()));
            newRow.setResult(row.getResult());
            this.rows.add(newRow);
        }
        currentRow.set(rows.size() - 1);
    }

    public void setLatestNameAndDescription(String name, String description) {
        if ((dataSetDescriptors == null) || (dataSetDescriptors.isEmpty())) {
            dataSetDescriptors = ImmutableList.of(new DataSetDescriptor(0,0,name,description));
        } else {
            dataSetDescriptors = replaceLatestDescriptor(last(dataSetDescriptors).withNameAndDescription(name, description));
        }
    }

    private List replaceLatestDescriptor(DataSetDescriptor updatedLatestDescriptor) {
        List previousDescriptors = dataSetDescriptors.subList(0, dataSetDescriptors.size() - 1);

        return new ImmutableList.Builder()
                .addAll(previousDescriptors)
                .add(updatedLatestDescriptor)
                .build();
    }

    public void startNewDataSet(String name, String description) {
        updateLatestRowCount();
        dataSetDescriptors = new ImmutableList.Builder()
                            .addAll(dataSetDescriptors)
                            .add(new DataSetDescriptor(rows.size(), 0, name, description))
                            .build();


    }

    private void updateLatestRowCount() {
        DataSetDescriptor currentDescriptor = last(dataSetDescriptors);
        int currentRowCount = rows.size() - currentDescriptor.getStartRow();
        dataSetDescriptors = replaceLatestDescriptor(currentDescriptor.withRowCount(currentRowCount));
    }

    private DataSetDescriptor last(List dataSetDescriptors) {
        return dataSetDescriptors.get(dataSetDescriptors.size() - 1);
    }

    public boolean hasPredefinedRows() {
        return predefinedRows;
    }

    public int getSize() {
        return rows.size();
    }

    public List getDataSets() {
        List dataSets = Lists.newArrayList();
        for (DataSetDescriptor descriptor : dataSetDescriptors) {
            dataSets.add(new DataSet(descriptor.getStartRow(),
                    descriptor.getRowCount(),
                    descriptor.getName(),
                    descriptor.getDescription(),
                    rows));
        }
        return dataSets;
    }

    public static class DataTableBuilder {
        final List headers;
        final List rows;
        final String description;
        final String title;
        final List descriptors;

        public DataTableBuilder(List headers) {
            this(headers, NO_ROWS, null, null, ImmutableList.of(DataSetDescriptor.DEFAULT_DESCRIPTOR));
        }

        public DataTableBuilder(List headers, List rows, String title,
                                String description, List descriptors) {
            this.headers = headers;
            this.rows = rows;
            this.description = description;
            this.title = title;
            this.descriptors = descriptors;
        }

        public DataTableBuilder andCopyRowDataFrom(DataTableRow row) {
            List rows = new ArrayList();
            rows.add(new DataTableRow(row.getValues()));
            return new DataTableBuilder(headers, rows, title, description, descriptors);
        }

        public DataTableBuilder andTitle(String title) {
            return new DataTableBuilder(headers, rows, title, description, descriptors);
        }

        public DataTableBuilder andDescription(String description) {
            return new DataTableBuilder(headers, rows, title, description, descriptors);
        }

        public DataTable build() {
            return new DataTable(headers, rows, title, description, descriptors);
        }

        public DataTableBuilder andRows(List> rows) {
            return new DataTableBuilder(headers, convert(rows, toDataTableRows()), title, description, descriptors);
        }

        public DataTableBuilder andRowData(List rows) {
            return new DataTableBuilder(headers, rows, title, description, descriptors);
        }


        public DataTableBuilder andDescriptors(List descriptors) {
            return new DataTableBuilder(headers, rows, title, description, descriptors);
        }

        public DataTableBuilder andMappedRows(List> mappedRows) {
            List> rowData = Lists.newArrayList();
            for (Map mappedRow : mappedRows) {
                rowData.add(rowDataFrom(mappedRow));
            }
            return new DataTableBuilder(headers, convert(rowData, toDataTableRows()), title, description, descriptors);
        }

        private Converter, DataTableRow> toDataTableRows() {
            return new Converter, DataTableRow>() {

                public DataTableRow convert(List values) {
                    return new DataTableRow(values);
                }
            };
        }

        private List rowDataFrom(Map mappedRow) {
            List rowData = Lists.newArrayList();
            for (String header : headers) {
                rowData.add(mappedRow.get(header));
            }
            return rowData;
        }

    }

    public class RowValueAccessor {
        private final DataTable dataTable;
        private final int rowNumber;

        public RowValueAccessor(DataTable dataTable, int rowNumber) {
            this.dataTable = dataTable;
            this.rowNumber = rowNumber;
        }

        public void hasResult(TestResult result) {
            dataTable.rows.get(rowNumber).updateResult(result);
        }

        public Map toStringMap() {
            Map rowData = new HashMap();
            int i = 0;
            for (Object value : dataTable.rows.get(rowNumber).getValues()) {
                rowData.put(dataTable.headers.get(i), value.toString());
                i++;
            }

            return rowData;

        }
    }
}