Hi Guys!
Sorry for jumping into the middle of the discussion, but I was
thinking on an alternative solution. Before going into the
implementation of the different tricky patterns, like subset,
intersect, etc. maybe we should slice the problem up. We already have
a good framework for calculating set operations (union, intersect,
etc.): LINQ
Here is my solution:
We need a class that represents an "abstract" instance. Abstract means
it can be a row in the table or a real instance. Let's call this
TableRowOrInstance<TInstance> for the sake of simplicity. Imagine that
this has a proper equals method (see my dummy implementation below),
and you have extension methods that can "convert" a table or a set of
instances to this form:
public static IEnumerable<TableRowOrInstance<TInstance>>
AsAbstractInstanceSet<TInstance>(this Table table)
{
return table.Rows.Select(r => new
TableRowOrInstance<TInstance>(r));
}
public static IEnumerable<TableRowOrInstance<TInstance>>
AsAbstractInstanceSet<TInstance>(this IEnumerable<TInstance>
instances)
{
return instances.Select(i => new
TableRowOrInstance<TInstance>(i));
}
With this a subset assertion could be formulated this way:
table.AsAbstractInstanceSet<SetComparisonTestObject>().Except(items.AsAbstractInstanceSet()).ShouldBeEmpty();
(note that the Except here is the LINQ Except method, there you can do
anything else, like Intersect() or SequentialEqual())
What do you think? I'm not 100% sure (especially with the naming), but
maybe this gives you ideas.
Here is the dummy code for the TableRowOrInstance<TInstance>, sorry
that it is a bit long:
public class TableRowOrInstance<TInstance>
{
public TableRow TableRow { get; private set; }
public TInstance Instacne { get; private set; }
public bool IsRow { get { return TableRow != null; } }
public bool IsInstance { get { return !IsRow; } }
public TableRowOrInstance(TableRow tableRow)
{
TableRow = tableRow;
}
public TableRowOrInstance(TInstance instacne)
{
Instacne = instacne;
}
public override int GetHashCode()
{
return 42; //unfortunately it is impossible to calculate a
proper hashcode
}
public override bool Equals(object obj)
{
TableRowOrInstance<TInstance> other = obj as
TableRowOrInstance<TInstance>;
if (other == null)
{
if (obj is TableRow)
other = new
TableRowOrInstance<TInstance>((TableRow)obj);
else if (obj is TInstance)
other = new
TableRowOrInstance<TInstance>((TInstance)obj);
else
return false;
}
if (IsInstance && other.IsInstance)
return Equals(Instacne, other.Instacne);
if (IsRow && other.IsRow)
return Equals(TableRow, other.TableRow); //TODO: we
need an equals on the TableRow
if (IsRow)
{
Debug.Assert(other.IsInstance);
//TODO: invoke Assist.CompareInstance but without the
exception
return CompareToSetTmp(TableRow, other.Instacne);
}
Debug.Assert(IsInstance);
Debug.Assert(other.IsRow);
return CompareToSetTmp(other.TableRow, Instacne);
}
// this is a temporary hack now
private static bool CompareToSetTmp(TableRow tableRow,
TInstance instance)
{
try
{
var table = new Table(tableRow.Select(r =>
r.Key).ToArray());
table.AddRow(tableRow.Select(r => r.Value).ToArray());
table.CompareToSet(new[] { instance });
return true;
}
catch (Exception)
{
return false;
> ...
>
> read more »