Skip to content

Commit

Permalink
add instance of comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
Bogdan Szabo committed Jan 22, 2021
1 parent c91b5ca commit fd78e4f
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 108 deletions.
20 changes: 10 additions & 10 deletions source/fluentasserts/core/base.d
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ auto should(T)(lazy T testData, const string file = __FILE__, const size_t line
} else static if(!returned) {

static if(is(T == class) || is(T == interface)) {
return ShouldObject!T(testData.evaluate);
return expect(testData, file, line);
} else {
return expect(testData, file, line);
}
Expand All @@ -520,7 +520,7 @@ unittest {
struct Assert {
static void opDispatch(string s, T, U)(T actual, U expected, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto sh = actual.should;
auto sh = expect(actual);

static if(s[0..3] == "not") {
sh.not;
Expand Down Expand Up @@ -548,7 +548,7 @@ struct Assert {

static void between(T, U)(T actual, U begin, U end, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.be.between(begin, end);
auto s = expect(actual, file, line).to.be.between(begin, end);

if(reason != "") {
s.because(reason);
Expand All @@ -557,7 +557,7 @@ struct Assert {

static void notBetween(T, U)(T actual, U begin, U end, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.not.be.between(begin, end);
auto s = expect(actual, file, line).not.to.be.between(begin, end);

if(reason != "") {
s.because(reason);
Expand All @@ -566,7 +566,7 @@ struct Assert {

static void within(T, U)(T actual, U begin, U end, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.be.within(begin, end);
auto s = expect(actual, file, line).to.be.between(begin, end);

if(reason != "") {
s.because(reason);
Expand All @@ -575,7 +575,7 @@ struct Assert {

static void notWithin(T, U)(T actual, U begin, U end, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.not.be.within(begin, end);
auto s = expect(actual, file, line).not.to.be.between(begin, end);

if(reason != "") {
s.because(reason);
Expand All @@ -584,7 +584,7 @@ struct Assert {

static void approximately(T, U, V)(T actual, U expected, V delta, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.be.approximately(expected, delta);
auto s = expect(actual, file, line).to.be.approximately(expected, delta);

if(reason != "") {
s.because(reason);
Expand All @@ -593,7 +593,7 @@ struct Assert {

static void notApproximately(T, U, V)(T actual, U expected, V delta, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.not.be.approximately(expected, delta);
auto s = expect(actual, file, line).not.to.be.approximately(expected, delta);

if(reason != "") {
s.because(reason);
Expand All @@ -602,7 +602,7 @@ struct Assert {

static void beNull(T)(T actual, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.beNull;
auto s = expect(actual, file, line).to.beNull;

if(reason != "") {
s.because(reason);
Expand All @@ -611,7 +611,7 @@ struct Assert {

static void notNull(T)(T actual, string reason = "", const string file = __FILE__, const size_t line = __LINE__)
{
auto s = actual.should.not.beNull(file, line);
auto s = expect(actual, file, line).not.to.beNull;

if(reason != "") {
s.because(reason);
Expand Down
1 change: 0 additions & 1 deletion source/fluentasserts/core/callable.d
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ unittest {
}).should.throwException!CustomException.thrown;

thrown.should.not.beNull;
thrown.should.be.instanceOf!CustomException;
thrown.msg.should.equal("test");
(cast(CustomException) thrown).data.should.equal(2);
}
Expand Down
74 changes: 71 additions & 3 deletions source/fluentasserts/core/evaluation.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import std.traits;
import std.conv;
import std.range;
import std.array;
import std.algorithm : map;

import fluentasserts.core.serializers;
import fluentasserts.core.results;
Expand All @@ -26,10 +27,18 @@ struct ValueEvaluation {
string niceValue;

/// The name of the type before it was converted to string
string typeName;
string[] typeNames;

/// Other info about the value
string[string] meta;

string typeName() @safe nothrow {
if(typeNames.length == 0) {
return "unknown";
}

return typeNames[0];
}
}

///
Expand Down Expand Up @@ -89,15 +98,15 @@ auto evaluate(T)(lazy T testData) @trusted if(!isInputRange!T || isArray!T || is
auto duration = Clock.currTime - begin;
auto serializedValue = SerializerRegistry.instance.serialize(value);
auto niceValue = SerializerRegistry.instance.niceValue(value);
return Result(value, ValueEvaluation(null, duration, serializedValue, niceValue, unqualString!TT));
return Result(value, ValueEvaluation(null, duration, serializedValue, niceValue, extractTypes!TT ));
} catch(Throwable t) {
T result;

static if(isCallable!T) {
result = testData;
}

return Result(result, ValueEvaluation(t, Clock.currTime - begin, result.to!string, result.to!string, unqualString!T));
return Result(result, ValueEvaluation(t, Clock.currTime - begin, result.to!string, result.to!string, extractTypes!T ));
}
}

Expand All @@ -124,3 +133,62 @@ unittest {
assert(result.evaluation.throwable !is null);
assert(result.evaluation.throwable.msg == "message");
}

string[] extractTypes(T)() if((!isArray!T && !isAssociativeArray!T) || isSomeString!T) {
string[] types;

types ~= unqualString!T;

static if(is(T == class)) {
static foreach(Type; BaseClassesTuple!T) {
types ~= unqualString!Type;
}
}

static if(is(T == interface) || is(T == class)) {
static foreach(Type; InterfacesTuple!T) {
types ~= unqualString!Type;
}
}

return types;
}

string[] extractTypes(T: U[], U)() if(isArray!T && !isSomeString!T) {
return extractTypes!(U).map!(a => a ~ "[]").array;
}

string[] extractTypes(T: U[K], U, K)() {
string k = unqualString!(K);
return extractTypes!(U).map!(a => a ~ "[" ~ k ~ "]").array;
}

/// It can get the type of a string
unittest {
auto result = extractTypes!string;
assert(result == ["string"]);
}

/// It can get the type of a string list
unittest {
auto result = extractTypes!(string[]);
assert(result == ["string[]"]);
}

/// It can get the type of a string assoc array
unittest {
auto result = extractTypes!(string[string]);
assert(result == ["string[string]"]);
}

/// It can get all types of a class
unittest {
interface I {}
class T : I {}

auto result = extractTypes!(T[]);

assert(result[0] == "fluentasserts.core.evaluation.__unittest_L185_C1.T[]");
assert(result[1] == "object.Object[]");
assert(result[2] == "fluentasserts.core.evaluation.__unittest_L185_C1.I[]");
}
16 changes: 13 additions & 3 deletions source/fluentasserts/core/expect.d
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import fluentasserts.core.lifecycle;
import fluentasserts.core.evaluation;
import fluentasserts.core.results;

import fluentasserts.core.serializers;

import std.traits;
import std.string;
import std.uni;
Expand Down Expand Up @@ -171,6 +173,14 @@ import std.conv;
return opDispatch!"containOnly"(value);
}

auto beNull() {
return opDispatch!"beNull";
}

auto instanceOf(Type)() {
return opDispatch!"instanceOf"(fullyQualifiedName!Type);
}

auto approximately(T, U)(T value, U range) {
return opDispatch!"approximately"(value, range);
}
Expand Down Expand Up @@ -238,13 +248,13 @@ import std.conv;
///
Expect expect(void delegate() callable, const string file = __FILE__, const size_t line = __LINE__, string prependText = null) @trusted {
ValueEvaluation value;
value.typeName = "callable";
value.typeNames = [ "callable" ];

try {
if(callable !is null) {
callable();
} else {
value.typeName = "null";
value.typeNames = ["null"];
}
} catch(Exception e) {
value.throwable = e;
Expand Down Expand Up @@ -294,4 +304,4 @@ unittest {
expect("".toNiceOperation).to.equal("");
expect("a.b".toNiceOperation).to.equal("a b");
expect("aB".toNiceOperation).to.equal("a b");
}
}
10 changes: 7 additions & 3 deletions source/fluentasserts/core/lifecycle.d
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import fluentasserts.core.base;
import fluentasserts.core.evaluation;
import fluentasserts.core.operations.approximately;
import fluentasserts.core.operations.arrayEqual;
import fluentasserts.core.operations.beNull;
import fluentasserts.core.operations.between;
import fluentasserts.core.operations.contain;
import fluentasserts.core.operations.endWith;
import fluentasserts.core.operations.equal;
import fluentasserts.core.operations.greaterThan;
import fluentasserts.core.operations.instanceOf;
import fluentasserts.core.operations.lessThan;
import fluentasserts.core.operations.registry;
import fluentasserts.core.operations.startWith;
import fluentasserts.core.operations.throwable;
import fluentasserts.core.operations.beNull;
import fluentasserts.core.results;
import fluentasserts.core.serializers;

import std.meta;
import std.conv;
import std.datetime;

alias BasicNumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real);
alias NumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real, ifloat, idouble, ireal, cfloat, cdouble, creal, char, wchar, dchar);
Expand All @@ -32,8 +34,8 @@ static this() {

Registry.instance = new Registry();

Registry.instance.register("Duration", "Duration", "lessThan", &lessThanDuration);
Registry.instance.register("Duration", "Duration", "below", &lessThanDuration);
Registry.instance.register!(Duration, Duration)("lessThan", &lessThanDuration);
Registry.instance.register!(Duration, Duration)("below", &lessThanDuration);

Registry.instance.register("string", "string", "equal", &equal);
Registry.instance.register("bool", "bool", "equal", &equal);
Expand Down Expand Up @@ -101,6 +103,8 @@ static this() {
Registry.instance.register(Type.stringof, "char", "endWith", &endWith);
}

Registry.instance.register("*", "*", "instanceOf", &instanceOf);

Registry.instance.register("callable", "", "throwAnyException", &throwAnyException);
Registry.instance.register("callable", "", "throwException", &throwException);

Expand Down
Loading

0 comments on commit fd78e4f

Please sign in to comment.