1717import static fj .data .PriorityQueue .emptyInt ;
1818import static fj .test .Arbitrary .arbAlphaNumString ;
1919import static fj .test .Arbitrary .arbInteger ;
20+ import static fj .test .Arbitrary .arbList ;
21+ import static fj .test .Arbitrary .arbP2 ;
2022import static fj .test .Arbitrary .arbSet ;
2123import static fj .test .Property .impliesBoolean ;
2224import static fj .test .Property .prop ;
2325import static fj .test .Property .property ;
26+ import static org .hamcrest .CoreMatchers .equalTo ;
27+ import static org .junit .Assert .assertThat ;
2428
2529/**
2630 * Created by MarkPerry on 18 Jun 16.
2933@ CheckParams (maxSize = 100 )
3034public class PriorityQueueProperties {
3135
32- public static Gen <PriorityQueue <Integer , String >> arbPriorityQueueIntegerString = arbUniqueQueue (arbAlphaNumString );
36+ public static Gen <PriorityQueue <Integer , String >> arbPriorityQueueIntegerString = arbQueue (arbAlphaNumString );
3337
3438 /**
3539 * Returns a queue with unique integer priorities.
@@ -43,6 +47,11 @@ public static <A> Gen<PriorityQueue<Integer, A>> arbUniqueQueue(Gen<A> aa) {
4347 return (alp .map (l -> PriorityQueue .<A >emptyInt ().enqueue (l )));
4448 }
4549
50+ public static <A > Gen <PriorityQueue <Integer , A >> arbQueue (Gen <A > aa ) {
51+ Gen <List <P2 <Integer , A >>> g = arbList (arbP2 (arbInteger , aa ));
52+ return g .map (l -> PriorityQueue .<A >emptyInt ().enqueue (l ));
53+ }
54+
4655 Property empty () {
4756 PriorityQueue <Integer , Object > pq = emptyInt ();
4857 return prop (pq .isEmpty ());
@@ -53,11 +62,10 @@ Property empty() {
5362 */
5463 Property addRemove () {
5564 return property (arbPriorityQueueIntegerString , arbInteger , arbAlphaNumString , (q , i , s ) -> {
56- Option <P2 <Integer , String >> o = q .top ();
57- Option <P2 <Integer , String >> o2 = q .enqueue (i , s ).dequeue ().top ();
58- return Property .impliesBoolean (
59- q .isGreaterThan (Ord .intOrd , i ),
60- () -> o .equals (o2 )
65+ Option <P2 <Integer , String >> t1 = q .top ();
66+ Option <P2 <Integer , String >> t2 = q .enqueue (i , s ).dequeue ().top ();
67+ return prop (q .isLessThan (Ord .intOrd , i ) ?
68+ t1 .equals (t2 ) : t2 .map (p -> p ._1 () >= i ).orSome (true )
6169 );
6270 });
6371 }
@@ -75,20 +83,36 @@ Property emptyTop() {
7583 Property addTop () {
7684 return property (arbPriorityQueueIntegerString , arbInteger , arbAlphaNumString , (q , i , s ) -> {
7785 Option <P2 <Integer , String >> actual = q .enqueue (i , s ).top ();
78- return impliesBoolean (
79- q .isGreaterThan (Ord .intOrd , i ),
80- actual .equals (some (P .p (i , s ))));
86+ return prop (q .isLessThan (Ord .intOrd , i ) ? actual .equals (some (P .p (i , s ))) : actual .equals (q .top ()));
8187 });
8288 }
8389
8490 /**
85- * Sorting a list returns the same as putting the list into a priority queue and getting
86- * the queue as a list.
91+ * Sorting a list returns the same as putting the list into a priority queue and getting the queue as a list.
8792 */
8893 public Property sorted () {
8994 return property (arbPriorityQueueIntegerString , pq -> {
9095 List <P2 <Integer , String >> expected = pq .toList ().sort (Ord .p2Ord1 (Ord .intOrd .reverse ()));
91- return prop (expected .equals (pq .toList ()));
96+ List <P2 <Integer , String >> actual = pq .toList ();
97+ assertThat (actual , equalTo (expected ));
98+ return prop (actual .equals (expected ));
99+ });
100+ }
101+
102+ /**
103+ * Where the top n of the queue has just one element then:
104+ * - Enqueueing and then topN of the queue should return a list of the top and the new item
105+ * - Enqueuing and then dequeueing and then topping the queue should return the new item
106+ */
107+ Property singleTopSame () {
108+ return property (arbPriorityQueueIntegerString , arbAlphaNumString , (pq , s ) -> {
109+ Option <Integer > o1 = pq .top ().map (p -> p ._1 ());
110+ return o1 .map (j -> {
111+ boolean b = pq .topN ().length () == 1 ;
112+ Property p1 = impliesBoolean (b , () -> pq .enqueue (j , s ).dequeue ().top ().equals (some (P .p (j , s ))));
113+ Property p2 = impliesBoolean (b , () -> pq .enqueue (j , s ).topN ().equals (List .list (pq .top ().some (), P .p (j , s ))));
114+ return p1 .and (p2 );
115+ }).orSome (prop (true ));
92116 });
93117 }
94118
0 commit comments