Dart unit test framework's `expect` does not seem to work properly - unit-testing

Here is an object's de to compare MapState:
class MapState {
final Coordinate currentCoordinate;
final Iterable<Coordinate> markers;
MapState(this.currentCoordinate, this.markers);
MapState.empty()
: this.currentCoordinate = null,
this.markers = [];
MapState.withCoordinate(this.currentCoordinate) : this.markers = [];
MapState.withMarkers(this.markers) : this.currentCoordinate = null;
MapState newCoordinate(final Coordinate coordinate) =>
MapState(coordinate, this.markers);
MapState newMarkersSet(final Iterable<Coordinate> markers) =>
MapState(this.currentCoordinate, markers);
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is MapState &&
runtimeType == other.runtimeType &&
currentCoordinate == other.currentCoordinate &&
markers == other.markers;
#override
int get hashCode =>
currentCoordinate.hashCode ^
markers.hashCode;
}
Here is the unit-test:
test('init, Observer should receive an empty state as a first state',
() {
expect(MapState.empty(), MapState.empty());
});
Result (failure, of course):
Expected: Instance of 'MapState'
Actual: Instance of 'MapState'
package:test_api expect
package:flutter_test/src/widget_tester.dart 196:3 expect
test/application/map_bloc_test.dart 25:5 main.
I simplified the primal test to this to track the error down, so don't get confused by the senseless of the unit-test.
Changing expect(MapState.empty(), MapState.empty()); to expect(1, 1); helps, but I can't get it working with my objects.
Also, here is my imports block:
import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:taxi/application/map_bloc.dart';
import 'package:taxi/domain/map.dart';
P.S.: strangely, but changing this.markers = [] to this.markers = const [] helps. Wut??? Anyway, expect([], []); works. That just doesn't make any sense to me.

The test fails because [] == [] is false in Dart. You can use the collection package to handle collection equality.

Related

Java: how to check for boolean conditions in two-dimensional lists/arrays?

Given a table-like data structure, e.g. an arraylist of arraylists (a 2D array, or some other iterable data structure), what would be the cleanest way to check the elements against specific rules?
For example given the following data:
[true, false, false, true]
[false, false, false, false]
[true, false, false, false]
How can I enforce that either of the three conditions are satisfied:
all elements in all rows are true
all elements in all rows are false
if a row contains mixed values, then only the first element can be true, otherwise the validation must fail.
For example, the data above must not pass validation because of a true value in position [0, 3].
UPDATE:
Apparently one way to avoid looping in Java 8 is using myBoolArrayList.stream().allMatch(Boolean::booleanValue); and myBoolArrayList.stream().noneMatch(Boolean::booleanValue); — this would cover the first two conditions, not very clear yet about the third condition.
Note that by looking at your three rules together, you don’t need to do individual checks:
A list can only contain all-true or all-false, but if either is valid, the combined rule is “all (boolean) values must be the same” which can be tested in a single expression like !booleanList.contains(!booleanList.get(0)). But there’s the third alternative:
if a row contains mixed values, then only the first element can be true, otherwise the validation must fail.
This basically says: if there is a false value, all but the first element must be false as well. This rule makes the other two obsolete:
if there is no false value, then all values are true
if there is a false value, the first element might be true, so all values being false is a special case of this rule
in other words, if there is a false value, the value of the first element is irrelevant
Therefore, we can short-cut the test by looking at any other element than the first one, e.g. at index 1 and selecting one rule to test, based on that value:
if the value is true, all values are required to be true
if the value is false, all but the first values are required to be false
as a corner case, if the list is smaller than two elements, there is no contradicting element, so the list is valid
So the entire condition can be expressed as
list.size()<2 ||
list.get(1)? // has a TRUE at a position other than the first
!list.contains(false): // all are TRUE
!list.subList(1, list.size()).contains(true); // all except the first are FALSE
Regarding the Stream API,
!list.contains(x) can be expressed as list.stream().noneMatch(Predicate.isEqual(x)) and
!list.subList(1, list.size()).contains(x) can be expressed as list.stream().skip(1).noneMatch(Predicate.isEqual(x)),
but there’s no reason to use the Stream API here.
However, for validating a List of Lists, you can use the Stream API to check whether all sublists fulfill the condition:
static boolean validate(List<List<Boolean>> list2D) {
return list2D.stream().allMatch(list-> list.size()<2 ||
list.get(1)? !list.contains(false): !list.subList(1, list.size()).contains(true)
);
}
You can use Guava libraries to check through the lists, for example:
[Updated: based on feedback... I don't think it's the nicest way, but it is a way of doing it].
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class ValidationTest {
#Test
public void test() {
// Here is the initial table, you can play with it.
List<List<Boolean>> list = new ArrayList<List<Boolean>>() {{
add(new ArrayList<Boolean>() {{
add(false);
add(false);
add(false);
add(false);
}});
add(new ArrayList<Boolean>() {{
add(true);
add(false);
add(false);
add(false);
}});
add(new ArrayList<Boolean>() {{
add(true);
add(true);
add(true);
add(true);
}});
}};
boolean checkBooleanRule = this.checkBooleanRule(list);
Assert.assertTrue("The table is invalid", checkBooleanRule);
}
private boolean checkRow(List<Boolean> row, final boolean value) {
// If checking everything is true/false, let's just find if there is a False = !value
return row.contains(!value);
}
private boolean checkBooleanRule(final List<List<Boolean>> inputList) {
// Gets the row that brake the rule!
Optional<List<Boolean>> invalidRow = Iterables.tryFind(inputList, new Predicate<List<Boolean>>() {
#Override
public boolean apply(List<Boolean> inputRow) {
if (!checkRow(inputRow, true))
return false;
if (!checkRow(inputRow, false))
return false;
return (inputRow.get(0) ? checkRow(inputRow.subList(1, inputRow.size()), false) : true);
}
});
// If Present, then, the Table is invalid! == There is a row with a false!
return !invalidRow.isPresent();
}
}
This is one way to do it, using Java Lambda expressions. Reference is here What is the best way to filter a Java Collection?
Update thanks to comments
import java.util.ArrayList;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
ArrayList<Boolean> array = new ArrayList<Boolean>();
array.add(true);
array.add(true);
array.add(true);
array.add(false);
//the simplest to read way
Stream<Boolean> arrayChecker = array.stream().filter(a -> a == true);
//Checks if the stream filter is equal to the array size. If so then all true
System.out.println(arrayChecker.count() == array.size() );
//the better way thanks to #ccpizza
Stream<Boolean> arrayChecker = array.stream().filter(Boolean::booleanValue);
//Even better way
array.stream().allMatch(Boolean::booleanValue);
//so basic I missed it. Thanks to #Holger
System.out.println(! array.contains(false));
}
}

Concise way to reduce where one of the states throws an exception

I have a bunch of these:
Validation<String, Foo> a;
Validation<String, Foo> b;
Validation<String, Foo> c;
Here are some of their methods:
boolean isValid();
boolean isInvalid(); // === !isValid()
String getError();
Now, I was trying to do this:
Stream.of(a, b, c).reduce(
Validation.valid(foo),
(a, b) -> a.isValid() && b.isValid()
? Validation.valid(foo)
: String.join("; ", a.getError(), b.getError())
);
There's the obvious issue that if only one of a or b is in error, then there's a needless ;. But there's a more serious issue: getError() throws an exception if the validation is valid.
Is there a way I can write this lambda (or use something else in the io.vavr.control.Validation library) without making all 4 cases (a && b, a && !b, !a && b, !a && !b) explicit?
EDIT
To be clearer, I wanted a result of Validation<String, Foo> in the end. I think it behaves like a "monad," in that way, but I'm not sure.
I think what you're trying to achieve is easier to solve in Either domain.
First, convert your stream of Validations to a stream of Eithers:
Stream<Either<String, Foo>> eithers = Stream.of(a, b, c)
.map(Validation::toEither);
then combine them:
Either<String, Foo> result = Either.sequence(eithers)
.mapLeft(seq -> seq.collect(Collectors.joining("; ")))
.map(combinator); // fill in with combinator function that converts
// a Seq<Foo> into a single Foo
Since you didn't specify how you want to combine multiple valid Foo objects into a single one, I left it open for you to fill in the combinator function in the above example.
Either.sequence(...) will reduce many eithers into a single one by returning an Either.Left containing the sequence of left values if any of the provided eithers is a left, or an Either.Right containing a (possibly empty) sequence of all right values, if none of the provided eithers is a left.
Update:
There's a Validation.sequence(...) method that can do it without converting into Either domain (which I somehow missed while creating my original answer -- thanks for pointing out):
Validation<Seq<String>, Seq<Foo>> validations = Validation.sequence(
Stream.of(a, b, c)
.map(v -> v.mapError(List::of))
);
Validation<String, Foo> result = validations
.mapError(errors -> errors.collect(Collectors.joining("; ")))
.map(combinator); // fill in with combinator function that converts
// a Seq<Foo> into a single Foo
You said that the Foo instances are the same, that means that you could use Seq::head in place of the combinator function. But you'll need to take care not to use an empty sequence of validations as input as it will cause Seq::head to throw NoSuchElementException in that case.
As I see, the output of your reduce is a string with the list of errors separated by ;.
You are mixing the accumulator parameters:
a is a partial result of the current reduction
b is the object itself that you are iterating
I'd do something like this:
Stream.of(a, b, c).reduce(
"", //initial state,
(prevState, validationObject) -> {
if (validationObject.isInvalid())
return prevState + ";" + validationObject.getError();
else
return prevState;
}
)
What about Collectors.groupingBy(). I think still you can improve false part set of string and join them, Output of below code is:
{false=[SomeException, ReallyBadProblem], true=[3, 5]}
Code example:
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Validation<String,Integer> a = new Validation<>(true, null, 3);
Validation<String,Integer> b = new Validation<>(true, null, 5);
Validation<String,Integer> c = new Validation<>(false, "SomeException", null);
Validation<String,Integer> d = new Validation<>(false, "ReallyBadProblem", null);
//Stream.of(a,b,c).collect(Collectors.groupingBy(v->v.isValid(), v->v.));
TreeMap<Boolean, Set<Object>> map = Stream.of(a,b,c,d).collect((groupingBy(v->v.isValid(), TreeMap::new,
mapping(v-> { return v.isValid() ? v.valid() : v.getError();}, toSet()))));
System.out.println(map);
}
public static class Validation<E, T>{
boolean valid;
T validVal;
String error;
public Validation(boolean valid, String error, T validVal) {
super();
this.valid = valid;
this.error = error;
this.validVal = validVal;
}
/**
* #return the valid
*/
public boolean isValid() {
return valid;
}
/**
* #param valid the valid to set
*/
public void setValid(boolean valid) {
this.valid = valid;
}
/**
* #return the error
*/
public String getError() {
return error;
}
/**
* #param error the error to set
*/
public void setError(String error) {
this.error = error;
}
public T valid() {
return validVal;
}
}
}
This is the way I ended up going, though I think #Nandor (accepted answer) had it right. (His solution was based on a more current version of io.vavr.control.Validation than what's available to me (still javaslang.control.Validation). I figured out that mapLeft was renamed to mapErrors, but there were some missing bits related to Seq manipulation. Due to lack of familiarity with Java, I was unable to resolve my errors going this route.)
Validation<String, AdRequest> validation =
Stream.of(
validateTargetingRequest(adRequest),
validateFlightRequest(adRequest, ad),
validateCreativeRequest(adRequest)
).reduce(
Validation.valid(adRequest),
(a, b) -> {
if (a.isValid() && b.isValid()) {
return Validation.valid(adRequest);
}
if (a.isInvalid() && b.isInvalid()) {
return Validation.invalid(String.join("; ", a.getError(), b.getError()));
}
// This seemingly overcomplicated structure was necessitated by the fact that getError
// throws an exception when called on an Valid form of Validation.
return a.isInvalid() ? a : b;
}
);

how to port java inner function in Scala?

How can I port a java inner function from here
which fully is contained in to Scala?
JavaPairRDD<Envelope, HashSet<Point>> castedResult = joinListResultAfterAggregation.mapValues(new Function<HashSet<Geometry>,HashSet<Point>>()
{
#Override
public HashSet<Point> call(HashSet<Geometry> spatialObjects) throws Exception {
HashSet<Point> castedSpatialObjects = new HashSet<Point>();
Iterator spatialObjectIterator = spatialObjects.iterator();
while(spatialObjectIterator.hasNext())
{
castedSpatialObjects.add((Point)spatialObjectIterator.next());
}
return castedSpatialObjects;
}
});
return castedResult;
My approach as outlined below would not compile due to some NotinferredU
val castedResult = joinListResultAfterAggregation.mapValues(new Function[java.util.HashSet[Geometry], java.util.HashSet[Point]]() {
def call(spatialObjects: java.util.HashSet[Geometry]): java.util.HashSet[Point] = {
val castedSpatialObjects = new java.util.HashSet[Point]
val spatialObjectIterator = spatialObjects.iterator
while (spatialObjectIterator.hasNext) castedSpatialObjects.add(spatialObjectIterator.next.asInstanceOf[Point])
castedSpatialObjects
}
})
When asking a question about compilation errors please provide the exact error, especially when your code doesn't stand on its own.
The inner function itself is fine; my guess would be that due to changes above joinListResultAfterAggregation isn't a JavaPairRDD anymore, but a normal RDD[(Envelope, Something)] (where Something could be java.util.HashSet, scala.collection.Set or some subtype), so its mapValues takes a Scala function, not a org.apache.spark.api.java.function.Function. Scala functions are written as lambdas: spatialObjects: Something => ... (the body will depend on what Something actually is, and the argument type can be omitted in some circumstances).
How about this ?
val castedResult = joinListResultAfterAggregation.mapValues(spatialObjects => {
spatialObjects.map(obj => (Point) obj)
})

Passing functions to functions in Kotlin

I am starting to use Vaadin with Kotlin, and have created the following extension method:
fun AbstractComponentContainer.addButton(buttonText : String = "", icon : FontIcon? = null, function : (() -> Unit)? = null) {
val button = Button(buttonText)
if (icon != null) {
button.icon = icon
}
if (function!=null) {
button.addClickListener { function() }
}
this.addComponent(button)
}
This lets me add a button to a container, with an optional click listener (and an optional icon).
I now want to add two buttons to the component, one for up, one for down, to allow me to move items up and down a list. Therefore, I want to call addButton() twice. The logic in the lambda is going to be the same, the only difference is that in one the item's position will be incremented and in the other decremented.
I am trying to create a function that can be passed to the addClickListener, and to save me writing two functions that do almost the same thing, I want to be able to pass to that function a reference to Long::plusAssign and Long::minusAssign.
I can't get it to work. Either it won't compile or I get ClassCastExceptions when it runs.
This is where I have got to:
val function = { function: (Long) -> Long ->
val selectedItems: MutableSet<Item> = //get my items
if (selectedItems.size == 1) {
val elementAt = selectedItems.elementAt(0)
elementAt.position = function(elementAt.position)
Notification("Element's position is now ${elementAt.position}", "", Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent())
listDataProvider.refreshItem(elementAt)
}
}
buttonLayout.addButton(buttonText = "Up", function = function(Long::inc) as (()->Unit)?)
buttonLayout.addButton(buttonText = "Down", function = function(Long::dec) as (()->Unit)?)
If I remove the cast, it won't compile, and if I leave the cast, I get the following:
java.lang.ClassCastException: kotlin.Unit cannot be cast to kotlin.jvm.functions.Function0
Is there a way to achieve what I want? I don't really want to change the signature of the function expected by addButton.
(note this is a question about Kotlin, rather than about Vaadin, so I am leaving the Vaadin tag off)
What you are asking for is currying, and it is not supported in Kotlin. The workaround is to explicitly create new lambdas:
buttonLayout.addButton("Up", function = { function(Long::inc) })
buttonLayout.addButton("Down", function = { function(Long::dec) })
I don't agree with the solution of Voddan, it seems to be a trick to deal with a problem that we should not have.
The compiler says me that function is returning Unit instead of () -> Unit. It seems logical, so just make a function instead of an Unit:
val function = fun(longFunction: (Long) -> Long) = {
val selectedItems: MutableSet<Item> = //get my items
if (selectedItems.size == 1) {
val elementAt = selectedItems.elementAt(0)
elementAt.position = longFunction(elementAt.position)
Notification("Element's position is now ${elementAt.position}", "", Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent())
listDataProvider.refreshItem(elementAt)
}
}
So that you can simply do:
buttonLayout.addButton("Up", function = function(Long::inc))
buttonLayout.addButton("Down", function = function(Long::dec))
In some case and for readability purpose I would sometimes prefer a more explicit/naive solution (is this currying?):
val function = fun(longFunction: (Long) -> Long): () -> Unit {
return fun() {
val selectedItems: MutableSet<Item> = //get my items
if (selectedItems.size == 1) {
val elementAt = selectedItems.elementAt(0)
elementAt.position = longFunction(elementAt.position)
Notification("Element's position is now ${elementAt.position}", "", Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent())
listDataProvider.refreshItem(elementAt)
}
}
}
On my side it gives the same result, and I find it more natural to read, and easier for developers starting with Kotlin. I don't know if it is a kind of currying or not, but it's compiling and working on my side (tested by mocking the class/event from Vaadin).

Scala constructor for case classes question

I'm puzzled by something in Scala. I seem to have objects that have the same address, but different contents. I came across this issue while using Kiama. But to keep things simple, I boiled all the code down to this:
object CaseTests {
trait Attributable extends Product {
var parent: Attributable = null;
private def setChildConnections = {
var i : Int = 0
for (i <- 0 until productArity) {
productElement (i) match {
case c : Attributable => c.parent = this
case _ =>
}
}
}
setChildConnections
}
abstract class Tree extends Attributable { def id = super.toString }
case class Pair (left : Tree, right : Tree) extends Tree { println(this+" = "+super.toString + " = ("+left.id+", "+right.id+")"); }
case class Leaf (value : Int) extends Tree { println(this+" = "+super.toString); }
def main(args: Array[String]): Unit = {
val l1 = Leaf(1);
val l2 = Leaf(1);
val tree = Pair (Leaf (1), Pair (Leaf (1), Leaf (2)))
val Pair(left1: Tree, sub: Tree) = tree
val Pair(left2: Tree, right: Tree) = sub
println("left1 = "+left1.id)
println("left2 = "+left2.id)
println("left1.parent = "+left1.parent)
println("left2.parent = "+left2.parent)
}
}
When I run my test case, I get this as output:
Leaf(1) = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
Leaf(1) = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
Leaf(1) = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
Leaf(1) = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
Leaf(2) = org.modelica.v4.tests.full.CaseTests$Leaf#de2f8005
Pair(Leaf(1),Leaf(2)) = org.modelica.v4.tests.full.CaseTests$Pair#d8e41584 = (org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2, org.modelica.v4.tests.full.CaseTests$Leaf#de2f8005)
Pair(Leaf(1),Pair(Leaf(1),Leaf(2))) = org.modelica.v4.tests.full.CaseTests$Pair#6a311526 = (org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2, org.modelica.v4.tests.full.CaseTests$Pair#d8e41584)
left1 = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
left2 = org.modelica.v4.tests.full.CaseTests$Leaf#fe67d8d2
left1.parent = Pair(Leaf(1),Pair(Leaf(1),Leaf(2)))
left2.parent = Pair(Leaf(1),Leaf(2))
What I don't understand (and I suspect this is because I am missing some subtle point about equivalence in Scala/Java or perhaps I'm simply misinterpreting the output) is how left1 and left2 appear to have the same address (or am I misinterpreting that), but different parents?!
If somebody could set me straight, I would really appreciate it. Thanks.
P.S. - I'm running Scala 2.9, in case it matters.
left1 and left2 are not the same objects. Try println(left1 eq left2), it will print false. The default toString method calls Integer.toHexString(hashCode), so you're bound to get the same id if the hash code of two object matches. And here it does, because case classes automatically get a decent hashCode and equals implementation.
Just a note: System.identityHashCode() is an excellent trick, but note that it's also not always guaranteed to return a unique result -- I've seen it return identical numbers for two different live objects.

Resources