This table is a sequence of Tuple4 objects, where each tuple represents one row of the table.
The first element of each tuple comprise the first column of the table, the second element of
each tuple comprise the second column, and so on. This table also carries with it
a heading tuple that gives string names to the columns of the table.

A handy way to create a TableFor4 is via an apply factory method in the Table
singleton object provided by the Tables trait. Here's an example:

Because you supplied 4 members in each tuple, the type you'll get back will be a TableFor4.

The table provides an apply method that takes a function with a parameter list that matches
the types and arity of the tuples contained in this table. The apply method will invoke the
function with the members of each row tuple passed as arguments, in ascending order by index. (I.e.,
the zeroth tuple is checked first, then the tuple with index 1, then index 2, and so on until all the rows
have been checked (or until a failure occurs). The function represents a property of the code under test
that should succeed for every row of the table. If the function returns normally, that indicates the property
check succeeded for that row. If the function completes abruptly with an exception, that indicates the
property check failed and the apply method will complete abruptly with a
TableDrivenPropertyCheckFailedException that wraps the exception thrown by the supplied property function.

The usual way you'd invoke the apply method that checks a property is via a forAll method
provided by trait TableDrivenPropertyChecks. The forAll method takes a TableFor4 as its
first argument, then in a curried argument list takes the property check function. It invokes apply on
the TableFor4, passing in the property check function. Here's an example:

Because TableFor4 is a Seq[(A, B, C, D)], you can use it as a Seq. For example, here's how
you could get a sequence of Outcomes for each row of the table, indicating whether a property check succeeded or failed
on each row of the table:

for (row yield {
outcomeOf { row._1 should not equal (7) }
}

Note: the outcomeOf method, contained in the OutcomeOf trait, will execute the supplied code (a by-name parameter) and
transform it to an Outcome. If no exception is thrown by the code, outcomeOf will result in a
Succeeded, indicating the "property check"
succeeded. If the supplied code completes abruptly in an exception that would normally cause a test to fail, outcomeOf will result in
in a Failed instance containing that exception. For example, the previous for expression would give you:

defandThen[C](k: ((A, B, C, D)) ⇒ C): PartialFunction[Int, C]

Applies the passed property check function to each row of this TableFor4.

Applies the passed property check function to each row of this TableFor4.

If the property checks for all rows succeed (the property check function returns normally when passed
the data for each row), this apply method returns normally. If the property check function
completes abruptly with an exception for any row, this apply method wraps that exception
in a TableDrivenPropertyCheckFailedException and completes abruptly with that exception. Once
the property check function throws an exception for a row, this apply method will complete
abruptly immediately and subsequent rows will not be checked against the function.