Skip to content

Instantly share code, notes, and snippets.

@ilkerde
Created March 31, 2011 07:40
Show Gist options
  • Save ilkerde/895974 to your computer and use it in GitHub Desktop.
Save ilkerde/895974 to your computer and use it in GitHub Desktop.
What do you expect? Fail or Pass? Me expects Fail!
/* Question:
What do you expect from assertion below? Fail or Pass?
*/
List<string> aList = new List<string> { "any" };
List<string> anEmptyList = new List<string>();
aList.ShouldContain(anEmptyList); // this currently passes!
/*
My opinion: above assertion should fail. My spec for this is:
*/
public class when_a_list_contains_an_element_and_another_list_is_empty
{
It should_fail_the__ShouldContains__assertion =
() => SpecException.ShouldBeOfType<SpecificationException>();
Because of =
() => SpecException = Catch.Exception(() => AList.ShouldContain(AnotherList));
Establish context =
() =>
{
Element = "An Element";
AList = new List<string> {Element};
AnotherList = new List<string>();
};
static Exception SpecException;
static List<string> AList;
static List<string> AnotherList;
static string Element;
}
/*
What do you think?
*/
@ilkerde
Copy link
Author

ilkerde commented Apr 1, 2011

@forki Thanks indeed for this great insight about type relevance. I didn't thought about this aspect before. Nonetheless, my initial perspective is a slightly different one.

To be honest I was a little puzzled after your comment regarding empty sets. Although your argumentation was fine and very plausible for me, I didn't feel like "yeah, this is what I wanted to do". I made up my mind about it yesterday and came to my personal conclusion that I failed to describe my intents and perspective in a precise manner.

That said, I strive to get better in communication. I'm willing to try to lay down my thoughts and "issues" with ShouldContain assertion once more. As a side note, I consider myself weak in formal languages and theoretical background. Hence, please bear with me if my explanation lacks formal/math correctness. Thanks.

Your hint regarding the wording of ShouldContain led me to the point to re-address my "uncomfyness" with the assertion. You said that it is indeed a difference whether it is being tested that set B is a subset of A or that sequence D is a subsequence of C. My expectation on the term Contains was different, though. For me, Contains expressed (in my particular context) something like "a true containment of B in A". Let's see if I can describe this a little better:

A = {a,b,c} , B = {b} , C = {}

naturally,

A.Contains(B) && A.Contains(C) && B.Contains(C) == true

However, my expectation was constrained on the cardinality of all sets, as

|A| > 0 , |B| > 0 , |C| > 0

which effectively whould render to

A.ContainsConstrained(B) == true && A.ContainsConstrained(C) == false

I think in math this should be exactly the same as:

Given a set A and B, it must be A ∩ B != {} and A ∩ B = B

Expressed in words: I want to assert that B is a non-empty set which is a full subset of A. Note: There's no relevance of order in stated constraints. Having said this, it's clear for me that "my expectation" of ShouldContain requires a clear wording. While thinking about this and reading more about empty sets, I stumbled over the term Inhabited Set (http://en.wikipedia.org/wiki/Inhabited_set). Basically, an inhabited set requires to be non-empty (I know that this is not really true for some logical models, nonetheless it is a viable expression in classical logic). With this background, I'd like to think about the elements of this non-empty "Inhabited set" as Inhabitants. A strong method name which then maps to all above stated contraints would then imho be something like
ShouldContainAllInhabitantsOf

So that I can state in my observations:
A.ShouldContainAllInhabitantsOf(B)

I truly hope that my second attempt in describing my "issue" on ShouldContain was a little better.
Please let me know if this makes sense for you, since I value any feedback to improve myself.

@forki
Copy link

forki commented Apr 1, 2011

Hi Ilker,

Given a set A and B, it must be A ∩ B != {} and A ∩ B = B

this can be reduced to:

B != {} and A ∩ B = B

I would write this as two expression:

It should_be_a_subset_of_A = () => A.ShouldContainAllElementsOf(B);
It should_be_nonempty = () => B.ShouldNotBeEmpty();

I think this separation is valid since the mathematical notation also distincts both cases and it would be good to communicate this in the specs. It also reads better in the error report (it might be the case that only one statement is broken).

Inhabited Sets might be a valid solution but I think Constructivism terms and arguments are not that widespread. ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment