diff --git a/assets/css/site.css b/assets/css/site.css
index b0ea25d8..d761d54b 100644
--- a/assets/css/site.css
+++ b/assets/css/site.css
@@ -80,3 +80,22 @@ iframe {
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
+
+table {
+ border: solid 1px silver;
+ padding: 3px;
+}
+
+table th {
+ border: solid 1px silver;
+ padding: 3px;
+}
+
+table td {
+ border: solid 1px silver;
+ padding: 3px;
+}
+
+td.blob-num {
+ border: none;
+}
diff --git a/index.md b/index.md
index 9c08bbca..32901aa9 100644
--- a/index.md
+++ b/index.md
@@ -23,7 +23,7 @@ title:
* [Class Level](#class-level)
* [Debugger Support](#debugger-support)
* [Console App](#console-app)
-- [Async/await support](#asyncawait-support)
+- [Async/Await Support](#asyncawait-support)
* [Class Level](#class-level-1)
* [Context level](#context-level)
- [Data-driven test cases](#data-driven-test-cases)
@@ -195,7 +195,8 @@ the debugger will pop right up:
System.Diagnostics.Debugger.Launch()
```
-NSpec also includes `DebuggerShim.cs` when you install it via Nuget. So you can use TDD.NET/ReSharper to run your tests.
+NSpec also includes `DebuggerShim.cs` when you install it via
+Nuget. So you can use TDD.NET/ReSharper to run your tests.
### Console App ###
@@ -210,242 +211,136 @@ Then you can debug everything like you would any other program. More
importantly, creating your own console app gives you the _power_ to
tailor input and output to your liking using NSpecs's API/constructs.
-## Async/await support
+## Async/Await Support ##
+
Your NSpec tests can run asynchronous code too.
-### Class level
-
-At a class level, you still declare hook methods with same names, but they must be *asynchronous* and return `async Task`, instead of `void`:
-
-```c#
-public class an_example_with_async_hooks_at_class_level : nspec
-{
- // Note the different return type and modifier
-
- async Task before_each()
- {
- await SetupScenarioAsync();
- }
-
- async Task act_each()
- {
- await DoActAsync();
- }
-
- void it_should_do_something()
- {
- DoSomething();
- }
-
- async Task it_should_do_something_async()
- {
- await DoSomethingAsync();
- }
-
- void after_each()
- {
- CleanupScenario();
- }
-
- // ...
-}
-```
-
-For all sync test hooks at class level you can find its corresponding async one, just by turning its signature to async:
-
-| Sync | Async |
-| --- | --- |
-| `void before_all()` | `async Task before_all()` |
-| `void before_each()` | `async Task before_each()` |
-| `void act_each()` | `async Task act_each()` |
-| `void it_xyz()` | `async Task it_xyz()` |
-| `void specify_xyz()` | `async Task specify_xyz()` |
-| `void after_each()` | `async Task after_each()` |
-| `void after_all()` | `async Task after_all()` |
-
-Throughout the test class you can run both sync and async expectations as needed, so you can freely mix `void it_xyz()` and `async Task it_abc()`.
-
-Given a class context, for each test execution phase (_before all_/ _before_/ _act_/ _after_/ _after all_) you can choose to run either sync or async code according to your needs: so in the same class context you can mix e.g. `void before_all()` with `async Task before_each()`, `void act_each()` and `async Task after_each()`.
-What you **can't** do is to assign both sync and async hooks for the same phase, in the same class context: so e.g. the following will not work and break your build at compile time (for the same rules of method overloading):
-
-```c#
-public class a_wrong_example_mixing_async_hooks_at_class_level : nspec
-{
- // Watch out, this example will not work
-
- void before_each() // this one, together with ...
- {
- SetupScenario();
- }
-
- async Task before_each() // ... this other, will cause an error
- {
- await SetupScenarioAsync();
- }
-
- async Task act_each()
- {
- await DoActAsync();
- }
-
- void it_should_do_something()
- {
- DoSomething();
- }
-
- async Task it_should_do_something_async()
- {
- await DoSomethingAsync();
- }
-
- void after_each()
- {
- CleanupScenario();
- }
-
- // ...
-}
-```
-
-### Context level
-
-At a context and sub-context level, you need to set _asynchronous_ test hooks provided by NSpec, instead of the synchronous ones:
-
-```c#
-public class an_example_with_async_hooks_at_context_level : nspec
-{
- void given_some_context()
- {
- // Note the 'Async' suffix
-
- beforeAsync = async () => await SetupScenarioAsync();
-
- it["should do something"] = () => DoSomething();
-
- itAsync["should do something async"] = async () => await DoSomethingAsync();
-
- context["given some nested scenario"] = () =>
- {
- before = () => SetupNestedScenario();
-
- actAsync = async () => await DoActAsync();
-
- itAsync["is not yet implemented async"] = todoAsync;
-
- afterAsync = async () => await CleanupNestedScenarioAsync();
- };
-
- after = () => CleanupScenario();
- }
+### Class Level ###
+
- // ...
-}
-```
+At a class level, you still declare hook methods with same names, but
+they must be *asynchronous* and return `async Task`, instead of
+`void`:
-For almost all sync test hooks and helpers you can find its corresponding async one:
+
-| Sync | Async |
-| --- | --- |
-| `beforeAll` | `beforeAllAsync` |
-| `before` | `beforeAsync` |
-| `beforeEach` | `beforeEachAsync` |
-| `act` | `actAsync` |
-| `it` | `itAsync` |
-| `xit` | `xitAsync` |
-| `expect` | `expectAsync` |
-| `todo` | `todoAsync` |
-| `after` | `afterAsync` |
-| `afterEach` | `afterEachAsync` |
-| `afterAll` | `afterAllAsync` |
-| `specify` | Not available |
-| `xspecify` | Not available |
-| `context` | Not needed, context remains sync |
-| `xcontext` | Not needed, context remains sync |
-| `describe` | Not needed, context remains sync |
-| `xdescribe` | Not needed, context remains sync |
+For all sync test hooks at class level you can find its corresponding
+async one, just by turning its signature to async:
-Throughout the whole test class you can run both sync and async expectations as needed, so you can freely mix `it[]` and `itAsync[]`.
+| Sync | Async
+| -------------------- | ---------------------------
+| `void before_all()` | `async Task before_all()`
+| `void before_each()` | `async Task before_each()`
+| `void act_each()` | `async Task act_each()`
+| `void it_xyz()` | `async Task it_xyz()`
+| `void specify_xyz()` | `async Task specify_xyz()`
+| `void after_each()` | `async Task after_each()`
+| `void after_all()` | `async Task after_all()`
-Given a single context, for each test execution phase (_before all_/ _before_/ _act_/ _after_/ _after all_) you can choose to run either sync or async code according to your needs: so in the same context you can mix e.g. `beforeAll` with `beforeAsync`, `act` and `afterAsync`.
-What you **can't** do is to assign both sync and async hooks for the same phase, in the same context: so e.g. the following will not work and throw an exception at runtime:
+Throughout the test class you can run both sync and async expectations
+as needed, so you can freely mix `void it_xyz()` and `async Task
+it_abc()`.
-```c#
-public class a_wrong_example_mixing_async_hooks_at_context_level : nspec
-{
- // Watch out, this example will not work
+Given a class context, for each test execution phase (_before all_/
+_before_/ _act_/ _after_/ _after all_) you can choose to run either
+sync or async code according to your needs: so in the same class
+context you can mix e.g. `void before_all()` with `async Task
+before_each()`, `void act_each()` and `async Task after_each()`.
- void given_some_scenario()
- {
- // this one, together with ...
- before = () => SetupScenario();
+What you **can't** do is to assign both sync and async hooks for the
+same phase, in the same class context: so e.g. the following will not
+work and break your build at compile time (for the same rules of
+method overloading):
- // ... this other, will cause an error
- beforeAsync = async () => await SetupScenarioAsync();
+
- it["should do something sync"] = () => DoSomething();
+### Context level ###
+
- itAsync["should do something async"] = async () => await DoSomethingAsync();
+At a context and sub-context level, you need to set _asynchronous_
+test hooks provided by NSpec, instead of the synchronous ones:
+
+
+
+For almost all sync test hooks and helpers you can find its
+corresponding async one:
+
+| Sync | Async
+| ------------ | ---------------------------------
+| `beforeAll` | `beforeAllAsync`
+| `before` | `beforeAsync`
+| `beforeEach` | `beforeEachAsync`
+| `act` | `actAsync`
+| `it` | `itAsync`
+| `xit` | `xitAsync`
+| `expect` | `expectAsync`
+| `todo` | `todoAsync`
+| `after` | `afterAsync`
+| `afterEach` | `afterEachAsync`
+| `afterAll` | `afterAllAsync`
+| `specify` | Not available
+| `xspecify` | Not available
+| `context` | Not needed, context remains sync
+| `xcontext` | Not needed, context remains sync
+| `describe` | Not needed, context remains sync
+| `xdescribe` | Not needed, context remains sync
+
+Throughout the whole test class you can run both sync and async
+expectations as needed, so you can freely mix `it[]` and `itAsync[]`.
+
+Given a single context, for each test execution phase (_before all_/
+_before_/ _act_/ _after_/ _after all_) you can choose to run either
+sync or async code according to your needs: so in the same context you
+can mix e.g. `beforeAll` with `beforeAsync`, `act` and `afterAsync`.
+
+What you **can't** do is to assign both sync and async hooks for the
+same phase, in the same context: so e.g. the following will not work
+and throw an exception at runtime:
+
+
+
+If you want to dig deeper for any level, whether class- or context-,
+you might directly have a look at how async support is tested in NSpec
+unit tests.
- context["given some nested scenario"] = () =>
- {
- before = () => SetupNestedScenario();
+Just look for `nspec`-derived classes in following files:
- itAsync["is not yet implemented async"] = todoAsync;
+* [Async Assert Tests](https://github.com/nspec/NSpec/tree/master/sln/test/NSpecSpecs/describe_RunningSpecs)
+* [How Before/After Async is Implemented](https://github.com/nspec/NSpec/tree/master/sln/test/NSpecSpecs/describe_RunningSpecs/describe_before_and_after)
- afterAsync = async () => await CleanupNestedScenarioAsync();
- };
+## Data-driven test cases ##
+
- after = () => CleanupScenario();
- }
+Test frameworks of the xUnit family have dedicated attributes in order
+to support data-driven test cases (so-called *theories*). NSpec, as a
+member of the xSpec family, does not make use of attributes and
+instead obtains the same result with a set of expectations
+automatically created through code. In detail, to set up a data-driven
+test case with NSpec you just:
- // ...
-}
-```
+1. Build a set of data points.
+1. Name and assign an expectation for each data point by looping though the whole set.
-If you want to dig deeper for any level, whether class- or context-, you might directly have a look at how async support is tested in NSpec unit tests.
-Just look for `nspec`-derived classes in following files:
+Any NSpec test runner will be able to detect all the (aptly) named
+expectations and run them. Here you can see a sample test case, where
+we took advantage of `NSpec.Each<>` class and `NSpec.Do()` extension
+to work more easily with data point enumeration, and `NSpec.With()`
+extension to have an easier time composing text:
-* [NSpecSpecs/describe_RunningSpecs/describe_async_*](https://github.com/nspec/NSpec/tree/master/NSpecSpecs/describe_RunningSpecs)
-* [NSpecSpecs/describe_RunningSpecs/describe_before_and_after/async_*](https://github.com/nspec/NSpec/tree/master/NSpecSpecs/describe_before_and_after)
-* [NSpecSpecs/describe_RunningSpecs/Exceptions/when_async_*](https://github.com/nspec/NSpec/tree/master/NSpecSpecs/describe_RunningSpecs/Exceptions)
-
-## Data-driven test cases
-
-Test frameworks of the xUnit family have dedicated attributes in order to support data-driven test cases (so-called *theories*). NSpec, as a member of the xSpec family, does not make use of attributes and instead obtains the same result with a set of expectations automatically created through code. In detail, to set up a data-driven test case with NSpec you just:
-
-1. build a set of data points;
-1. name and assign an expectation for each data point by looping though the whole set.
-
-Any NSpec test runner will be able to detect all the (aptly) named expectations and run them. Here you can see a sample test case, where we took advantage of `NSpec.Each<>` class and `NSpec.Do()` extension to work more easily with data point enumeration, and `NSpec.With()` extension to have an easier time composing text:
-
-```c#
-public class describe_prime_factors : nspec
-{
- void given_first_ten_integer_numbers()
- {
- new Each
- {
- { 0, new int[] { } },
- { 1, new int[] { } },
- { 2, new[] { 2 } },
- { 3, new[] { 3 } },
- { 4, new[] { 2, 2 } },
- { 5, new[] { 5 } },
- { 6, new[] { 2, 3 } },
- { 7, new[] { 7 } },
- { 8, new[] { 2, 2, 2 } },
- { 9, new[] { 3, 3 } },
-
- }.Do((given, expected) =>
- it["{0} should be {1}".With(given, expected)] = () => given.Primes().should_be(expected)
- );
- }
-}
-```
+
## Additional info
+
### Order of execution
+
-Please have a look at [this wiki page](https://github.com/nspec/NSpec/wiki/Execution-Orders) for an overview on which test hooks are executed when: execution order in xSpec family frameworks can get tricky when dealing with more complicated test configurations, like inherithing from an abstract test class or mixing `before_each` with `before_all` at different context levels.
+Please have a look
+at
+[this wiki page](https://github.com/nspec/NSpec/wiki/Execution-Orders)
+for an overview on which test hooks are executed when: execution order
+in xSpec family frameworks can get tricky when dealing with more
+complicated test configurations, like inherithing from an abstract
+test class or mixing `before_each` with `before_all` at different
+context levels.