<commit_before>unit-threaded
=============

| [![Build Status](https://travis-ci.org/atilaneves/unit-threaded.png?branch=master)](https://travis-ci.org/atilaneves/unit-threaded) |  [![Build Status](https://ci.appveyor.com/api/projects/status/github/atilaneves/unit-threaded?branch=master&svg=true)](https://ci.appveyor.com/project/atilaneves/unit-threaded) | [![Coverage](https://codecov.io/gh/atilaneves/unit-threaded/branch/master/graph/badge.svg)](https://codecov.io/gh/atilaneves/unit-threaded) |

[My DConf2016 Lightning talk demonstrating unit-threaded](https://www.youtube.com/watch?v=yIH_0ew-maI#t=6m50s).

Multi-threaded advanced unit test framework for [the D programming language](https://dlang.org/).

Augments D's `unittest` blocks with:

* Tests can be named and individually run
* Custom assertions for better error reporting (e.g. 1.should == 2)
* Runs in threads by default
* UDAs for customisation of tests
* Value and type parameterized tests
* Property based testing
* Mocking


Quick start with dub
----------------------

dub runs tests with `dub test`. Unfortunately, due to the nature of
D's compile-time reflection, to use this library a test runner file
listing all modules to reflect on must exist. Since this is a tedious
task and easily automated, unit-threaded has a dub configuration
called `gen_ut_main` to do just that.  To use unit-threaded with a dub
project, you can use a `unittest` configuration as exemplified in this
`dub.json`:

```json
{
    "name": "myproject",
    "targetType": "executable",
    "targetPath": "bin",
    "configurations": [
        { "name": "executable" },
        {
            "name": "unittest",
            "targetType": "executable",
            "preBuildCommands": ["dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"],
            "mainSourceFile": "bin/ut.d",
            "excludedSourceFiles": ["src/main.d"],
            "dependencies": {
                "unit-threaded": "*"
            }
        }
    ]
}
```

With `dub.sdl`:

```
configuration "executable" {
}

configuration "unittest" {
    dependency "unit-threaded" version="*"
    mainSourceFile "bin/ut.d"
    excludedSourceFiles "src/main.d"
    targetType "executable"
    preBuildCommands "dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"
}

```

`excludedSourceFiles` is there to not compile the file containing the
`main` function to avoid linker errors. As an alternative to using
`excludedSourceFiles`, the "real" `main` can be versioned out:

```d
version(unittest) {}
else {
    void main() {
        //...
    }
}
```

Your unittest blocks will now be run in threads and can be run individually.
To name each unittest, simply attach a string UDA to it:

```d
@("Test that 2 + 3 is 5")
unittest {
    assert(2 + 3 == 5);
}
```

You can also have multiple configurations for running unit tests, e.g. one that uses
the standard D runtime unittest runner and one that uses unit-threaded:


    "configurations": [
        {"name": "ut_default"},
        {
          "name": "unittest",
          "preBuildCommands: ["dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"],
          "mainSourceFile": "bin/ut.d",
          ...
        }
    ]


In this example, `dub test -c ut_default` runs as usual if you don't use this
library, and `dub test` runs with the unit-threaded test runner.

To use unit-threaded's assertions or UDA-based features, you must import the library:

```d
// Don't use `version(unittest)` here - if anyone depends on your code and
// doesn't depend on unit-threaded they won't be able to test their own
// code!
version(TestingMyCode) { import unit_threaded; }
else                   { enum ShouldFail; }  // so production builds compile

int adder(int i, int j) { return i + j; }

@("Test adder") unittest {
    adder(2, 3).shouldEqual(5);
}

@("Test adder fails", ShouldFail) unittest {
    adder(2, 3).shouldEqual(7);
}
```

If using a custom dub configuration for unit-threaded as shown above, a version
block can be used on `Have_unit_threaded` (this is added by dub to the build).

Custom Assertions
-----------------
Code speaks louder than words:

```d
    1.should == 1;
    1.should.not == 2;
    1.should in [1, 2, 3];
    4.should.not in [1, 2, 3];

    void funcThrows() { throw new Exception("oops"); }
    funcThrows.should.throw_;

    // or with .be
    1.should.be == 1;
    1.should.not.be == 2;
    1.should.be in [1, 2, 3];
    4.should.not.be in [1, 2, 3];

    // I know this is operator overload abuse. I still like it.
    [1, 2, 3].should ~ [3, 2, 1];
    [1, 2, 3].should.not ~ [1, 2, 2];
    1.0.should ~ 1.0001;
    1.0.should.not ~ 2.0;
    ```

See more in the `unit_threaded.should` module.


Fast compilation mode
--------------------
Fast compilation mode. Set the version to `unitThreadedLight` and it will
compile much faster, but with no error reporting and certain features<commit_msg>Correct the markup in the README.<commit_after>unit-threaded
=============

| [![Build Status](https://travis-ci.org/atilaneves/unit-threaded.png?branch=master)](https://travis-ci.org/atilaneves/unit-threaded) |  [![Build Status](https://ci.appveyor.com/api/projects/status/github/atilaneves/unit-threaded?branch=master&svg=true)](https://ci.appveyor.com/project/atilaneves/unit-threaded) | [![Coverage](https://codecov.io/gh/atilaneves/unit-threaded/branch/master/graph/badge.svg)](https://codecov.io/gh/atilaneves/unit-threaded) |

[My DConf2016 Lightning talk demonstrating unit-threaded](https://www.youtube.com/watch?v=yIH_0ew-maI#t=6m50s).

Multi-threaded advanced unit test framework for [the D programming language](https://dlang.org/).

Augments D's `unittest` blocks with:

* Tests can be named and individually run
* Custom assertions for better error reporting (e.g. 1.should == 2)
* Runs in threads by default
* UDAs for customisation of tests
* Value and type parameterized tests
* Property based testing
* Mocking


Quick start with dub
----------------------

dub runs tests with `dub test`. Unfortunately, due to the nature of
D's compile-time reflection, to use this library a test runner file
listing all modules to reflect on must exist. Since this is a tedious
task and easily automated, unit-threaded has a dub configuration
called `gen_ut_main` to do just that.  To use unit-threaded with a dub
project, you can use a `unittest` configuration as exemplified in this
`dub.json`:

```json
{
    "name": "myproject",
    "targetType": "executable",
    "targetPath": "bin",
    "configurations": [
        { "name": "executable" },
        {
            "name": "unittest",
            "targetType": "executable",
            "preBuildCommands": ["dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"],
            "mainSourceFile": "bin/ut.d",
            "excludedSourceFiles": ["src/main.d"],
            "dependencies": {
                "unit-threaded": "*"
            }
        }
    ]
}
```

With `dub.sdl`:

```
configuration "executable" {
}

configuration "unittest" {
    dependency "unit-threaded" version="*"
    mainSourceFile "bin/ut.d"
    excludedSourceFiles "src/main.d"
    targetType "executable"
    preBuildCommands "dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"
}

```

`excludedSourceFiles` is there to not compile the file containing the
`main` function to avoid linker errors. As an alternative to using
`excludedSourceFiles`, the "real" `main` can be versioned out:

```d
version(unittest) {}
else {
    void main() {
        //...
    }
}
```

Your unittest blocks will now be run in threads and can be run individually.
To name each unittest, simply attach a string UDA to it:

```d
@("Test that 2 + 3 is 5")
unittest {
    assert(2 + 3 == 5);
}
```

You can also have multiple configurations for running unit tests, e.g. one that uses
the standard D runtime unittest runner and one that uses unit-threaded:


    "configurations": [
        {"name": "ut_default"},
        {
          "name": "unittest",
          "preBuildCommands: ["dub run unit-threaded -c gen_ut_main -- -f bin/ut.d"],
          "mainSourceFile": "bin/ut.d",
          ...
        }
    ]


In this example, `dub test -c ut_default` runs as usual if you don't use this
library, and `dub test` runs with the unit-threaded test runner.

To use unit-threaded's assertions or UDA-based features, you must import the library:

```d
// Don't use `version(unittest)` here - if anyone depends on your code and
// doesn't depend on unit-threaded they won't be able to test their own
// code!
version(TestingMyCode) { import unit_threaded; }
else                   { enum ShouldFail; }  // so production builds compile

int adder(int i, int j) { return i + j; }

@("Test adder") unittest {
    adder(2, 3).shouldEqual(5);
}

@("Test adder fails", ShouldFail) unittest {
    adder(2, 3).shouldEqual(7);
}
```

If using a custom dub configuration for unit-threaded as shown above, a version
block can be used on `Have_unit_threaded` (this is added by dub to the build).

Custom Assertions
-----------------
Code speaks louder than words:

```d
    1.should == 1;
    1.should.not == 2;
    1.should in [1, 2, 3];
    4.should.not in [1, 2, 3];

    void funcThrows() { throw new Exception("oops"); }
    funcThrows.should.throw_;

    // or with .be
    1.should.be == 1;
    1.should.not.be == 2;
    1.should.be in [1, 2, 3];
    4.should.not.be in [1, 2, 3];

    // I know this is operator overload abuse. I still like it.
    [1, 2, 3].should ~ [3, 2, 1];
    [1, 2, 3].should.not ~ [1, 2, 2];
    1.0.should ~ 1.0001;
    1.0.should.not ~ 2.0;
```

See more in the `unit_threaded.should` module.


Fast compilation mode
--------------------
Fast compilation mode. Set the version to `unitThreadedLight` and it will
compile much faster, but with no error reporting and certain features
{'fraction_non_alphanumeric': 0.1419387755102041, 'fraction_numerical': 0.014081632653061225, 'mean_word_length': 2.972841507904337, 'pattern_counts': {'":': 32, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 16, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7670560', 'n_tokens_mistral': 3275, 'n_tokens_neox': 3105, 'n_words': 1040}