A BDD fluent assertion library for D.
Forked from Yamadacpc's Pyjamas
import pyjamas;
10.should.equal(10);
5.should.not.equal(10);
[1, 2, 3, 4].should.include(3);
Pyjamas, and by extension Pijamas, is an assertion library heavily inspired by visionmedia'Ĺ› should.js module for Node.JS.
It aspires to be totally independent of the unit test runner and be IDE friendly. Also, it offers a fluent like syntax that allow to make human reaable assertions.
A failing assertation throws an AssertException with information of what was expected, and file and line number where it failed. An AssertException it's an alias to AsertError or to UnitTestException if Unit-thereaded it's present.
Simply add pijamas as a dependency :
dub.sdl:
configuration "unittest" {
dependency "pijamas" version="<current version>"
}
dub.json:
"configurations": [
{
"name": "unittest",
"dependencies": {
"pijamas": "<current version>"
}
}
]
And import pijamas where you nee it.
Pijamas haves a experimental support of nogc exceptions (thanks to mir-algorithm). This allow to use Pijamas on @nogc unittest blocks. Howeverm not the whole API it's allowed to be used on this way. For example, should.match(), depends on std.regex and isn't @nogc compatible.
To use this @nogc mode, simply use dub's subConfigurations to call the "nogc" configuration, and togle dip1008
. However, remeber that your unit-tests would have the mir-algorithm as indirect dependency.
dub.json:
"subConfigurations": {
"pijamas": "nogc"
}
Pijamas exports two functions should
and expect
meant for public use. Because of D's
lookup shortcut syntax, one is able to use both should(obj)
, expect(obj)
,
obj.should
and obj.expect
to get an object wrapped around an Assertion
instance.
These methods all are aliases for an identity function, returning the assertion instance without modification. This allows one to have a more fluent API, by chaining statements together:
10.should.be.equal(10);
[1, 2, 3, 4].should.have.length(4);
10.expect.to.not.be.equal(0);
This function negates the wrapper assertion. With it, one can express fluent assertions without much effort:
10.should.not.equal(2);
Asserts for equality between two objects. Returns the value wrapped around the assertion.
[1, 2, 3, 4].should.equal([1, 2, 3, 4]);
255.should.equal(10); // Throws an Exception "expected 255 to equal 10"
T approxEqual(U)(U other, U maxRelDiff = CommonDefaultFor!(T,U), U maxAbsDiff = 0.0, string file = __FILE__, size_t line = __LINE__);
Asserts for approximated equality of float types. Returns the value wrapped around the assertion. See Phobos std.math.isClose().
(1.0f).should.be.approxEqual(1.00000001);
(1.0f).should.not.be.approxEqual(1.01);
T close(U)(U other, U maxRelDiff = CommonDefaultFor!(T,U), U maxAbsDiff = 0.0, string file = __FILE__, size_t line = __LINE__);
Alias of approxEqual
Asserts whether a value exists - currently simply compares it with null
, if it
is convertible to null
(actually strings, pointers and classes). Returns the
value wrapped around the assertion.
auto exists = "I exist!";
should(exists).exist;
string doesntexist;
doesntexist.should.exist; // Throws an Exception "expected null to exist"
Asserts if a value is bigger than another value. Returns the result.
"z".should.be.biggerThan("a");
10.should.be.biggerThan(1);
Asserts if a value is bigger or euqal than another value. Returns the result.
10.should.be.biggerOrEqualThan(1);
10.should.be.biggerOrEqualThan(10);
Asserts if a value is smaller than another value. Returns the result.
10.should.be.smallerThan(100);
false.should.be.smallerThan(true);
Asserts if a value is smaller or equal than another value. Returns the result.
10.should.be.smallerOrEqualThan(100);
10.should.be.smallerOrEqualThan(10);
Asserts for an input range wrapped around an Assertion
to contain/include a
value.
[1, 2, 3, 4].should.include(3);
"something".should.not.include('o');
"something".should.include("th");
Note that not works with associative arrays on @nogc code.
Note that not works finding a substring of a string on @nogc code.
Asserts for the .length
property or function value to equal some value.
[1, 2, 3, 4].should.have.length(4);
"abcdefg".should.have.length(0);
// ^^ - Throws an Exception "expected 'abcdefg' to have length of 0"
Asserts that the .lenght property or function value is equal to 0;
[].should.be.empty;
"".expect.to.be.empty;
Asserts for a string wrapped around the Assertion to match a regular expression.
"something weird".expect.to.match(`[a-z]+`);
"something weird".should.match(regex(`[a-z]+`));
"something 2 weird".should.not.match(ctRegex!`^[a-z]+$`));
"1234numbers".should.match(`[0-9]+[a-z]+`);
"1234numbers".should.not.match(`^[a-z]+`);
Note that not works on @nogc code.
Both functions have the same signature.
Asserts for a boolean value to be equal to true
or to ``false.
true.should.be.True;
false.should.be.False;
Asserts whether a forward range is sorted.
[1, 2, 3, 4].should.be.sorted;
[1, 2, 0, 4].should.not.be.sorted;
Note that not works on @nogc code.
Asserts for an associative array to have a key equal to other
.
["something": 10].should.have.key("something");
Asserts whether a callable object wrapped around the assertion throws an exception of type T.
void throwing()
{
throw new Exception("I throw with 0!");
}
should(&throwing).Throw!Exception;
void notThrowing()
{
return;
}
should(¬Throwing).not.Throw;
I know the documentation is still somewhat lacking, but it's better than nothing, I guess? :)
Try looking at the test suite in tests/pyjamas_spec.d
to see some "real world" testing of the library.
BTW, I'll be glad to accept help in writting the documentation.
Run tests with:
dub test --root=tests/silly
but you can try any other test runner :
dub test --root=tests/unit-threaded
dub test --root=tests/dunit
dub test --root=tests/d-unit
dub run trial:runner@~master
A special config "fail-tests", exists (but only works on silly and on dunit) that enforces to fail some tests to help debug Pijamas mesages.
The original project was name "Pyjamas", a name that could be confuse, and have name clash on search engines, with Python's Pyjamas framework. So a new name sees a good idea. Pijamas is the word on Spanish and English for "Pyjamas", so it's a start. If anyone have a better name, hurry up to suggest it.
And the real why. Because Pyjamas had a nice syntax compared against others libraries, but sadly was abandoned.
Also, was the only barely working assert (at the time) library that don't poluttes dub.selections with unit-threaded when you aren't using unit-threaded. Even though we are using Silly testing runner, this library is supposed to be framework agnostic. The fact, it's tha the test suite has been testes running it with unit-threaded, dunit, d-unit, silly and trial.
This code is licensed under the MIT license. See the LICENSE file for more information.