deep_equal
deep_equal copied to clipboard
Helper for Deep Comparison
Deep Equal
Every programmer needs to compare values.
Basic Usage
var expected = // any value, array, objects, etc
var actual = // some other value
switch DeepEqual.compare(expected, actual) {
case Success(_): // they are value-identical
case Failure(f): trace(f.message, f.data); // they are different!
}
Advanced Usage
By default, string, bool, Int, float, date, bytes, int64, array, map, objects, class instances,
enum values, class/enum objects (Class<T>/Enum<T>) are recursively compared by value.
In case more advanced comparison (such as partial equals, regex checks, etc) is needed,
one can implement the CustomCompare interface and put it as the expected value.
The following shows an example on checking if an array contains some required elements, while not necessarily the same length as the required elements.
var a = [1,2,3,4];
var e = new ArrayContains([1,2,3]);
compare(e, a); // success, because the actual value contains all the required values 1, 2 and 3.
var a = [1,2,3,4];
var e = new ArrayContains([3,5]);
compare(e, a); // fail, because the actual value does not contain the required value 5.
class ArrayContains implements deepequal.CustomCompare {
var items:Array<Dynamic>;
public function new(items) {
this.items = items;
}
public function check(other:Dynamic, compare:Dynamic->Dynamic->Outcome<Noise, Error>) {
if(!Std.is(other, Array)) return Failure(new Error('Expected array but got $other'));
for(i in items) {
var matched = false;
for(o in (other:Array<Dynamic>)) switch compare(i, o) {
case Success(_): matched = true; break;
case Failure(_):
}
if(!matched) return Failure(new Error('Cannot find $i in $other'));
}
return Success(Noise);
}
}
Here are some more use case examples:
Assert array of certain length without caring about the contents
var actual = [1,2,3];
compare(new ArrayOfLength(3), actual)` // or;
compare([for(i in 0...3) new Anything()], actual);
Assert object with certain contents without doing a perfect match
var actual = {a:1, b:2}
compare(new ObjectContains({a: 1}), actual);
Assert an enum value and matches its first parameter as regex
var actual = Bar("MyString", 1); // suppose defined `enum Foo {Bar(s:String, i:Int)}`
compare(new EnumByName(Foo, 'Bar', [new Regex(~/MyS.*/), new Anything()]), actual);