All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
fit.RowFixture Maven / Gradle / Ivy
Go to download
The fully integrated standalone wiki, and acceptance testing framework.
// Modified or written by Object Mentor, Inc. for inclusion with FitNesse.
// Copyright (c) 2002 Cunningham & Cunningham, Inc.
// Released under the terms of the GNU General Public License version 2 or later.
// Copyright (c) 2002 Cunningham & Cunningham, Inc.
// Released under the terms of the GNU General Public License version 2 or later.
package fit;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public abstract class RowFixture extends ColumnFixture {
public Object[] results;
public List missing = new LinkedList<>();
public List surplus = new LinkedList<>();
@Override
public void doRows(Parse rows) {
try {
bindColumnHeadersToMethodsAndFields(rows.parts);
results = query();
match(list(rows.more), list(results), 0);
Parse last = rows.last();
last.more = buildRows(surplus.toArray());
mark(last.more, "surplus");
mark(missing.iterator(), "missing");
}
catch (Exception e) {
exception(rows.leaf(), e);
}
}
public abstract Object[] query() throws Exception; // get rows to be compared
@Override
public abstract Class> getTargetClass(); // get expected type of row
protected void match(List> expected, List> computed, int col) {
if (col >= columnBindings.length) {
check(expected, computed);
} else if (columnBindings[col] == null) {
match(expected, computed, col + 1);
} else {
Map eMap = eSort(expected, col);
Map cMap = cSort(computed, col);
Set keys = union(eMap.keySet(), cMap.keySet());
for (Object key : keys) {
List> eList = (List>) eMap.get(key);
List> cList = (List>) cMap.get(key);
if (eList == null) {
surplus.addAll(cList);
} else if (cList == null) {
missing.addAll(eList);
} else if (eList.size() == 1 && cList.size() == 1) {
check(eList, cList);
} else {
match(eList, cList, col + 1);
}
}
}
}
protected List list(Parse rows) {
List result = new LinkedList<>();
while (rows != null) {
result.add(rows);
rows = rows.more;
}
return result;
}
protected List list(Object[] rows) {
List result = new LinkedList<>();
Collections.addAll(result, rows);
return result;
}
protected Map eSort(List> list, int col) {
TypeAdapter a = columnBindings[col].adapter;
Map result = new ConcurrentHashMap<>(list.size());
for (Object o : list) {
Parse row = (Parse) o;
Parse cell = row.parts.at(col);
try {
Object key = a.parse(cell.text());
bin(result, key, row);
}
catch (Exception e) {
exception(cell, e);
for (Parse rest = cell.more; rest != null; rest = rest.more) {
ignore(rest);
}
}
}
return result;
}
protected Map cSort(List> list, int col) {
TypeAdapter a = columnBindings[col].adapter;
Map result = new ConcurrentHashMap<>(list.size());
for (Object row : list) {
try {
a.target = row;
Object key = a.get();
bin(result, key, row);
}
catch (Exception e) {
// surplus anything with bad keys, including null
surplus.add(row);
}
}
return result;
}
protected void bin(Map result, Object key, Object row) {
if (key.getClass().isArray()) {
key = Arrays.asList((Object[]) key);
}
if (result.containsKey(key)) {
((List) result.get(key)).add(row);
} else {
List list = new LinkedList<>();
list.add(row);
result.put(key, list);
}
}
protected Set union(Set> a, Set> b) {
Set result = new HashSet<>();
result.addAll(a);
result.addAll(b);
return result;
}
protected void check(List> eList, List> cList) {
if (eList.isEmpty()) {
surplus.addAll(cList);
return;
}
if (cList.isEmpty()) {
missing.addAll(eList);
return;
}
Parse row = (Parse) eList.remove(0);
Parse cell = row.parts;
Object obj = cList.remove(0);
for (int i = 0; i < columnBindings.length && cell != null; i++) {
TypeAdapter a = columnBindings[i].adapter;
if (a != null) {
a.target = obj;
}
check(cell, a);
cell = cell.more;
}
check(eList, cList);
}
protected void mark(Parse rows, String message) {
String annotation = label(message);
while (rows != null) {
wrong(rows.parts);
rows.parts.addToBody(annotation);
rows = rows.more;
}
}
protected void mark(Iterator> rows, String message) {
String annotation = label(message);
while (rows.hasNext()) {
Parse row = (Parse) rows.next();
wrong(row.parts);
row.parts.addToBody(annotation);
}
}
protected Parse buildRows(Object[] rows) {
Parse root = new Parse(null, null, null, null);
Parse next = root;
for (Object row : rows) {
next = next.more = new Parse("tr", null, buildCells(row), null);
}
return root.more;
}
protected Parse buildCells(Object row) {
if (row == null) {
Parse nil = new Parse("td", "null", null, null);
nil.addToTag(" colspan=" + columnBindings.length);
return nil;
}
Parse root = new Parse(null, null, null, null);
Parse next = root;
for (Binding columnBinding : columnBindings) {
next = next.more = new Parse("td", " ", null, null);
TypeAdapter a = columnBinding.adapter;
if (a == null) {
ignore(next);
} else {
try {
a.target = row;
next.body = gray(escape(a.toString(a.get())));
}
catch (Exception e) {
exception(next, e);
}
}
}
return root.more;
}
}