package de.axone.data.weighted; import org.assertj.core.api.AbstractIterableAssert; import org.testng.annotations.Test; import de.axone.data.weighted.WeightedCollectionContained.WeightedItem; import de.axone.tools.E; // import static de.axone.data.weighted.WeightedItemListAssert.*; @Test( groups="helper.weighted_collection" ) public class WeightedCollectionContainedTest { public void testOneItem() { TestWeightedItems<String> list = new TestWeightedItems<>(); list.add( "id1", 10.0 ); assertThat( list ) .hasSize( 1 ) .contains( "id1", 10 ) .hasWeight( 10.0 ) .hasMaxWeight( 10.0 ) .hasAvgWeight( 10.0 ) ; } public void testDifferentItems() { TestWeightedItems<String> list = new TestWeightedItems<>(); list.add( "id1", 10.0 ); list.add( "id2", 10.0 ); assertThat( list ) .hasSize( 2 ) .contains( "id1", 10.0 ) .contains( "id2", 10.0 ) .hasWeight( 20.0 ) .hasMaxWeight( 10.0 ) .hasAvgWeight( 10.0 ) ; } public void testSameItems() { TestWeightedItems<String> list = new TestWeightedItems<>(); list.add( "id1", 10.0 ); list.add( "id1", 20.0 ); assertThat( list ) .hasSize( 1 ) .contains( "id1", 30.0 ) .hasWeight( 30.0 ) .hasMaxWeight( 30.0 ) .hasAvgWeight( 30.0 ) ; } public void testMixedItems() { TestWeightedItems<String> list = new TestWeightedItems<>(); list.add( "id1", 10.0 ); list.add( "id1", 20.0 ); list.add( "id2", 20.0 ); assertThat( list ) .hasSize( 2 ) .contains( "id1", 30.0 ) .contains( "id2", 20.0 ) .hasWeight( 50.0 ) .hasMaxWeight( 30.0 ) .hasAvgWeight( 25.0 ) ; } public void testEquals() { TestWeightedItems<String> list1 = new TestWeightedItems<>(), list2 = new TestWeightedItems<>() ; assertThat( list1 ) .isEqualTo( list2 ) ; assertThat( list1.add( "test", 1 ) ) .isNotEqualTo( list2 ) ; assertThat( list2.add( "test", 1 ) ) .isEqualTo( list1 ) ; assertThat( list1.add( "test", 1 ) ) .isNotEqualTo( list2 ) ; assertThat( list2.add( "test", 1 ) ) .isEqualTo( list1 ) ; } public void testSublists() { TestWeightedItems<String> list = new TestWeightedItems<>(); assertThat( list ) .hasSize( 0 ) ; list.add( "id1", 10.0 ); list.add( "id2", 20.0 ); list.add( "id3", 30.0 ); list.add( "id4", 40.0 ); assertThat( list ) .hasSize( 4 ) ; assertThat( list.best( 0 ) ) .hasSize( 0 ) ; assertThat( list.best( 1 ) ) .print() .hasSize( 1 ) .contains( "id4", 40.0 ) .hasWeight( 40.0 ) .hasMaxWeight( 40.0 ) .hasAvgWeight( 40.0 ) ; assertThat( list.best( 2 ) ) .hasSize( 2 ) .contains( "id4", 40.0 ) .contains( "id3", 30.0 ) .hasWeight( 70.0 ) .hasMaxWeight( 40.0 ) .hasAvgWeight( 35.0 ) ; assertThat( list.best( 3 ) ) .hasSize( 3 ) .contains( "id4", 40 ) .contains( "id3", 30 ) .contains( "id2", 20 ) .hasWeight( 90.0 ) .hasMaxWeight( 40.0 ) .hasAvgWeight( 30.0 ) ; assertThat( list.best( 4 ) ) .hasSize( 4 ) .contains( "id4", 40 ) .contains( "id3", 30 ) .contains( "id2", 20 ) .contains( "id1", 10 ) .hasWeight( 100.0 ) .hasMaxWeight( 40.0 ) .hasAvgWeight( 25.0 ) ; assertThat( list.best( 5 ) ) .hasSize( 4 ) ; } public void testNormalize() { TestWeightedItems<String> list = new TestWeightedItems<>(); list.add( "id1", 10.0 ); list.add( "id2", 10.0 ); list.add( "id2", 10.0 ); list.add( "id3", 30.0 ); list.add( "id4", 40.0 ); assertThat( list ) .hasSize( 4 ) .hasWeight( 100.0 ) .hasAvgWeight( 25.0 ) .hasMaxWeight( 40.0 ) .contains( "id1", 10.0, 0.25 ) .contains( "id2", 20.0, 0.5 ) .contains( "id3", 30.0, 0.75 ) .contains( "id4", 40.0, 1.0 ) ; } private static class TestWeightedItems<S> extends AbstractWeightedCollectionContained<TestWeightedItems<S>,S> { public TestWeightedItems() { super( TestWeightedItems::new ); }} public static class WeightedCollectionContainedAssert<S,W extends AbstractWeightedCollectionContained<W,S>> extends AbstractIterableAssert<WeightedCollectionContainedAssert<S,W>, W, WeightedItem<S>> { protected WeightedCollectionContainedAssert( W actual ) { super( actual, WeightedCollectionContainedAssert.class ); } public WeightedCollectionContainedAssert<S,W> print() { E.echo( System.err, 2, true, true, false, actual ); return this; } public WeightedCollectionContainedAssert<S,W> hasWeight( double weight ){ org.assertj.core.api.Assertions.assertThat( actual.weight() ) .isEqualTo( weight ) ; return this; } public WeightedCollectionContainedAssert<S,W> hasMaxWeight( double weight ){ org.assertj.core.api.Assertions.assertThat( actual.maxWeight() ) .isEqualTo( weight ) ; return this; } public WeightedCollectionContainedAssert<S,W> hasAvgWeight( double weight ){ org.assertj.core.api.Assertions.assertThat( actual.avgWeight() ) .isEqualTo( weight ) ; return this; } public WeightedCollectionContainedAssert<S,W> contains( S item, double weight ){ WeightedItem<S> it = actual.new WeightedItemImpl( item, weight ); for( WeightedItem<S> check : actual ) { if( it.equals( check ) ) return this; } failWithMessage( "%s(%s) should be contained, but is not", item, weight ); return this; } public WeightedCollectionContainedAssert<S,W> contains( S item, double weight, double normalized ){ WeightedItem<S> it = new TestWeightedItem<>( item, weight, normalized ); for( WeightedItem<S> check : actual ) { if( check.equals( it ) ) return this; } failWithMessage( "%s(%s) should be contained, but is not", item, weight ); return this; } } public static <S,W extends AbstractWeightedCollectionContained<W,S>> WeightedCollectionContainedAssert<S,W> assertThat( W list ) { return new WeightedCollectionContainedAssert<>( list ) .as( list.toString() ) ; } private static final class TestWeightedItem<T> implements WeightedItem<T> { private final T item; private double weight; private Double normalized; TestWeightedItem( T item, double weight, double normalized ) { this.item = item; this.weight = weight; this.normalized = normalized; } @Override public T item() { return item; } @Override public double weight() { return weight; } @Override public double normalized() { return normalized != null ? normalized : -1; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ( ( item == null ) ? 0 : item.hashCode() ); long temp; temp = Double.doubleToLongBits( weight ); result = prime * result + (int) ( temp ^ ( temp >>> 32 ) ); return result; } @Override public boolean equals( Object obj ) { if( this == obj ) return true; if( obj == null ) return false; if( !( obj instanceof TestWeightedItem ) ) return false; WeightedItem<?> other = (WeightedItem<?>) obj; if( item == null ) { if( other.item() != null ) return false; } else if( !item.equals( other.item() ) ) return false; if( Double.doubleToLongBits( weight ) != Double .doubleToLongBits( other.weight() ) ) return false; if( normalized != null ) if( ! normalized.equals( other.normalized() ) ) return false; return true; } @Override public String toString() { return item.toString() + '(' + weight() + '/' + normalized() + ')'; } } }