diff --git a/source/fluentasserts/core/expect.d b/source/fluentasserts/core/expect.d index 41c300e..2a2e823 100644 --- a/source/fluentasserts/core/expect.d +++ b/source/fluentasserts/core/expect.d @@ -145,6 +145,11 @@ import std.conv; return opDispatch!"greaterThan"(value); } + /// + auto greaterOrEqualTo(T)(T value) { + return opDispatch!"greaterOrEqualTo"(value); + } + /// auto above(T)(T value) { return opDispatch!"above"(value); @@ -154,6 +159,11 @@ import std.conv; return opDispatch!"lessThan"(value); } + /// + auto lessOrEqualThan(T)(T value) { + return opDispatch!"lessOrEqualThan"(value); + } + /// auto below(T)(T value) { return opDispatch!"below"(value); diff --git a/source/fluentasserts/core/lifecycle.d b/source/fluentasserts/core/lifecycle.d index 5d23b03..f970b52 100644 --- a/source/fluentasserts/core/lifecycle.d +++ b/source/fluentasserts/core/lifecycle.d @@ -10,6 +10,7 @@ import fluentasserts.core.operations.contain; import fluentasserts.core.operations.endWith; import fluentasserts.core.operations.equal; import fluentasserts.core.operations.greaterThan; +import fluentasserts.core.operations.greaterOrEqualTo; import fluentasserts.core.operations.instanceOf; import fluentasserts.core.operations.lessThan; import fluentasserts.core.operations.registry; @@ -47,6 +48,7 @@ static this() { } static foreach(Type; BasicNumericTypes) { + Registry.instance.register(Type.stringof, Type.stringof, "greaterOrEqualTo", &greaterOrEqualTo!Type); Registry.instance.register(Type.stringof, Type.stringof, "greaterThan", &greaterThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "above", &greaterThan!Type); diff --git a/source/fluentasserts/core/operations/greaterOrEqualTo.d b/source/fluentasserts/core/operations/greaterOrEqualTo.d new file mode 100644 index 0000000..5a15c69 --- /dev/null +++ b/source/fluentasserts/core/operations/greaterOrEqualTo.d @@ -0,0 +1,55 @@ +module fluentasserts.core.operations.greaterOrEqualTo; + +import fluentasserts.core.results; +import fluentasserts.core.evaluation; + +import fluentasserts.core.lifecycle; + +import std.conv; + +version(unittest) { + import fluentasserts.core.expect; +} + +/// +IResult[] greaterOrEqualTo(T)(ref Evaluation evaluation) @safe nothrow { + evaluation.message.addText("."); + + T expectedValue; + T currentValue; + + try { + expectedValue = evaluation.expectedValue.strValue.to!T; + currentValue = evaluation.currentValue.strValue.to!T; + } catch(Exception e) { + return [ new MessageResult("Can't convert the values to " ~ T.stringof) ]; + } + + auto result = currentValue >= expectedValue; + + if(evaluation.isNegated) { + result = !result; + } + + if(result) { + return []; + } + + evaluation.message.addText(" "); + evaluation.message.addValue(evaluation.currentValue.strValue); + + IResult[] results = []; + + if(evaluation.isNegated) { + evaluation.message.addText(" is greater or equal than "); + results ~= new ExpectedActualResult("less than " ~ evaluation.expectedValue.strValue, evaluation.currentValue.strValue); + } else { + evaluation.message.addText(" is less than "); + results ~= new ExpectedActualResult("greater or equal than " ~ evaluation.expectedValue.strValue, evaluation.currentValue.strValue); + } + + evaluation.message.addValue(evaluation.expectedValue.strValue); + evaluation.message.addText("."); + + return results; +} diff --git a/test/operations/greaterOrEqualTo.d b/test/operations/greaterOrEqualTo.d new file mode 100644 index 0000000..616a7d8 --- /dev/null +++ b/test/operations/greaterOrEqualTo.d @@ -0,0 +1,55 @@ +module test.operations.greaterOrEqualTo; + +import fluentasserts.core.expect; +import fluent.asserts; + +import trial.discovery.spec; + +import std.string; +import std.conv; +import std.meta; + +alias s = Spec!({ + alias NumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real); + + static foreach(Type; NumericTypes) { + describe("using " ~ Type.stringof ~ " values", { + Type smallValue; + Type largeValue; + + before({ + smallValue = cast(Type) 40; + largeValue = cast(Type) 50; + }); + + it("should be able to compare two values", { + expect(largeValue).to.be.greaterOrEqualTo(smallValue); + expect(largeValue).to.be.greaterOrEqualTo(largeValue); + }); + + it("should be able to compare two values using negation", { + expect(smallValue).not.to.be.greaterOrEqualTo(largeValue); + }); + + it("should throw a detailed error when the comparison fails", { + auto msg = ({ + expect(smallValue).to.be.greaterOrEqualTo(largeValue); + }).should.throwException!TestException.msg; + + msg.split("\n")[0].should.equal(smallValue.to!string ~ " should be greater or equal to " ~ largeValue.to!string ~ ". " ~ smallValue.to!string ~ " is less than " ~ largeValue.to!string ~ "."); + msg.split("\n")[2].strip.should.equal("Expected:greater or equal than " ~ largeValue.to!string); + msg.split("\n")[3].strip.should.equal("Actual:" ~ smallValue.to!string); + }); + + it("should throw a detailed error when the negated coparison fails", { + auto msg = ({ + expect(largeValue).not.to.be.greaterOrEqualTo(smallValue); + }).should.throwException!TestException.msg; + + msg.split("\n")[0].should.equal(largeValue.to!string ~ " should not be greater or equal to " ~ smallValue.to!string ~ ". " ~ largeValue.to!string ~ " is greater or equal than " ~ smallValue.to!string ~ "."); + msg.split("\n")[2].strip.should.equal("Expected:less than " ~ smallValue.to!string); + msg.split("\n")[3].strip.should.equal("Actual:" ~ largeValue.to!string); + }); + }); + } +}); diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..358a1a3 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,25 @@ +/+dub.sdl: +dependency "fluent-asserts" version= "~>0.13.3" ++/ + +import std.stdio; +import fluent.asserts; + +void f2() { + int k = 3; + Assert.equal(k, 4); +} + +void f1() { + int j = 2; + f2(); +} + +void f0() { + int i = 1; + f1(); +} + +void main() { + f0(); +} \ No newline at end of file