[libgee] Added Collection.is_empty|add_all|contains_all|remove_all|retain_all



commit aa84c81b8039f7866c60311842a4e153306fedba
Author: Tomaž Vajngerl <quikee gmail com>
Date:   Sat Jul 25 17:24:41 2009 +0200

    Added Collection.is_empty|add_all|contains_all|remove_all|retain_all
    
    Fixes bug 589690.

 gee/abstractcollection.vala |   49 +++++
 gee/arraylist.vala          |   37 ++++
 gee/collection.vala         |   52 ++++++-
 gee/hashmap.vala            |   24 +++
 gee/readonlycollection.vala |   25 +++
 gee/readonlylist.vala       |   23 +++
 gee/readonlyset.vala        |   25 +++
 gee/treemap.vala            |   24 +++
 tests/testarraylist.vala    |  405 ++++++++++++++++++++++++++++++++++++++++++-
 tests/testhashset.vala      |  379 ++++++++++++++++++++++++++++++++++++++++-
 10 files changed, 1038 insertions(+), 5 deletions(-)
---
diff --git a/gee/abstractcollection.vala b/gee/abstractcollection.vala
index 6171cd9..a93c0e5 100644
--- a/gee/abstractcollection.vala
+++ b/gee/abstractcollection.vala
@@ -32,6 +32,10 @@ public abstract class Gee.AbstractCollection<G> : Object, Iterable<G>, Collectio
 
 	public abstract int size { get; }
 
+	public virtual bool is_empty {
+		get { return size == 0; }
+	}
+
 	public abstract bool contains (G item);
 
 	public abstract bool add (G item);
@@ -49,6 +53,51 @@ public abstract class Gee.AbstractCollection<G> : Object, Iterable<G>, Collectio
 		return array;
 	}
 
+	public virtual bool add_all (Collection<G> collection) {
+		if (collection.is_empty) {
+			return false;
+		}
+
+		bool changed = false;
+		foreach (G item in collection) {
+			changed = changed | add (item);
+		}
+		return changed;
+	}
+
+	public virtual bool contains_all (Collection<G> collection) {
+		if (collection.size > size) {
+			return false;
+		}
+
+		foreach (G item in collection) {
+			if (!contains (item)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public virtual bool remove_all (Collection<G> collection) {
+		bool changed = false;
+		foreach (G item in collection) {
+			changed = changed | remove (item);
+		}
+		return changed;
+	}
+
+	public virtual bool retain_all (Collection<G> collection) {
+		bool changed = false;
+		G[] items = to_array ();
+		int size_of_items = size;
+		for (int index = 0; index < size_of_items; index++) {
+			if (!collection.contains (items[index])) {
+				changed = changed | remove (items[index]);
+			} 
+		}
+		return changed;
+	}
+
 	//
 	// Inherited from Iterable<G>
 	//
diff --git a/gee/arraylist.vala b/gee/arraylist.vala
index f898002..467e8d0 100644
--- a/gee/arraylist.vala
+++ b/gee/arraylist.vala
@@ -138,6 +138,43 @@ public class Gee.ArrayList<G> : AbstractCollection<G>, List<G> {
 		return slice;
 	}
 
+	public override bool add_all (Collection<G> collection) {
+		if (collection.is_empty) {
+			return false;
+		}
+
+		grow_if_needed (collection.size);
+		foreach (G item in collection) {
+			_items[_size++] = item;
+		}
+		_stamp++;
+		return true;
+	}
+
+	public override bool remove_all (Collection<G> collection) {
+		bool changed = false;
+		for (int index = 0; index < _size; index++) {
+			if (collection.contains (_items[index])) {
+				remove_at (index);
+				index--;
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
+	public override bool retain_all (Collection<G> collection) {
+		bool changed = false;
+		for (int index = 0; index < _size; index++) {
+			if (!collection.contains (_items[index])) {
+				remove_at (index);
+				index--;
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
 	public override G[] to_array() {
 		G[] array = new G[_size];
 		Memory.copy(array, _items, sizeof(G) * _size);
diff --git a/gee/collection.vala b/gee/collection.vala
index c6012d2..2dca0ed 100644
--- a/gee/collection.vala
+++ b/gee/collection.vala
@@ -1,6 +1,6 @@
 /* collection.vala
  *
- * Copyright (C) 2007  Jürg Billeter
+ * Copyright (C) 2007-2009  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,6 +31,11 @@ public interface Gee.Collection<G> : Iterable<G> {
 	public abstract int size { get; }
 
 	/**
+	 * Specifies whether this collection is empty.
+	 */
+	public abstract bool is_empty { get; }
+
+	/**
 	 * Determines whether this collection contains the specified item.
 	 *
 	 * @param item the item to locate in the collection
@@ -66,6 +71,51 @@ public interface Gee.Collection<G> : Iterable<G> {
 	public abstract void clear ();
 
 	/**
+	 * Adds all items in the input collection to this collection.
+	 * 
+	 * @param collection the collection which items will be added to this 
+	 *                   collection.
+	 * 
+	 * @return     true if the collection has been changed, false otherwise
+	 */
+	public abstract bool add_all (Collection<G> collection);
+
+	/**
+	 * Returns true it this collection contains all items as the input 
+	 * collection.
+	 *
+	 * @param collection the collection which items will be compared with 
+	 *                   this collection.
+	 * 
+	 * @return     true if the collection has been changed, false otherwise
+	 */
+	public abstract bool contains_all (Collection<G> collection);
+
+	/**
+	 * Removes all items in this collection that are contained in the input 
+	 * collection. In other words all common items of both collections are 
+	 * removed from this collection.
+	 * 
+	 * @param collection the collection which items will be compared with
+	 *                   this collection.
+	 * 
+	 * @return     true if the collection has been changed, false otherwise
+	 */
+	public abstract bool remove_all (Collection<G> collection);
+
+	/**
+	 * Removes all items in this collection that are not contained in the input
+	 * collection. In other words all common items of both collections are
+	 * retained in this collection.
+	 * 
+	 * @param collection the collection which items will be compared with 
+	 *                   this collection.
+	 * 
+	 * @return     true if the collection has been changed, false otherwise
+	 */
+	public abstract bool retain_all (Collection<G> collection);
+
+	/**
 	 * Returns an array containing all of items from this collection.
 	 *
 	 * @return an array containing all of items from this collection
diff --git a/gee/hashmap.vala b/gee/hashmap.vala
index fe895da..824fae1 100644
--- a/gee/hashmap.vala
+++ b/gee/hashmap.vala
@@ -207,6 +207,18 @@ public class Gee.HashMap<K,V> : Object, Map<K,V> {
 		public override bool contains (K key) {
 			return _map.contains (key);
 		}
+
+		public override bool add_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool remove_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool retain_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
 	}
 
 	private class KeyIterator<K,V> : Object, Iterator<K> {
@@ -282,6 +294,18 @@ public class Gee.HashMap<K,V> : Object, Map<K,V> {
 			}
 			return false;
 		}
+
+		public override bool add_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool remove_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool retain_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
 	}
 
 	private class ValueIterator<K,V> : Object, Iterator<V> {
diff --git a/gee/readonlycollection.vala b/gee/readonlycollection.vala
index 5ed2da9..870eb1c 100644
--- a/gee/readonlycollection.vala
+++ b/gee/readonlycollection.vala
@@ -30,6 +30,10 @@ public class Gee.ReadOnlyCollection<G> : Object, Iterable<G>, Collection<G> {
 		get { return _collection.size; }
 	}
 
+	public bool is_empty {
+		get { return _collection.is_empty; }
+	}
+
 	public Collection<G> collection {
 		construct { _collection = value; }
 	}
@@ -72,6 +76,27 @@ public class Gee.ReadOnlyCollection<G> : Object, Iterable<G>, Collection<G> {
 		assert_not_reached ();
 	}
 
+	public bool add_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool contains_all (Collection<G> collection) {
+		foreach (G element in collection) {
+			if (!contains (element)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public bool remove_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool retain_all(Collection<G> collection) {
+		assert_not_reached ();
+	}
+
 	public G[] to_array() {
 		return _collection.to_array ();
 	}
diff --git a/gee/readonlylist.vala b/gee/readonlylist.vala
index 2c4f1e5..eb5bab4 100644
--- a/gee/readonlylist.vala
+++ b/gee/readonlylist.vala
@@ -30,6 +30,10 @@ public class Gee.ReadOnlyList<G> : Object, Iterable<G>, Collection<G>, List<G> {
 		get { return _list.size; }
 	}
 
+	public bool is_empty {
+		get { return _list.is_empty; }
+	}
+
 	public List<G> list {
 		construct { _list = value; }
 	}
@@ -104,6 +108,25 @@ public class Gee.ReadOnlyList<G> : Object, Iterable<G>, Collection<G>, List<G> {
 		assert_not_reached ();
 	}
 
+	public bool add_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool contains_all (Collection<G> collection) {
+		if (_list == null) {
+			return false;
+		}
+		return _list.contains_all (collection);
+	}
+
+	public bool remove_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool retain_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
 	public G[] to_array() {
 		return _list.to_array ();
 	}
diff --git a/gee/readonlyset.vala b/gee/readonlyset.vala
index a2e6572..b7bdb7a 100644
--- a/gee/readonlyset.vala
+++ b/gee/readonlyset.vala
@@ -30,6 +30,10 @@ public class Gee.ReadOnlySet<G> : Object, Iterable<G>, Collection<G>, Set<G> {
 		get { return _set.size; }
 	}
 
+	public bool is_empty {
+		get { return _set.is_empty; }
+	}
+
 	public new Set<G> set {
 		construct { _set = value; }
 	}
@@ -72,6 +76,27 @@ public class Gee.ReadOnlySet<G> : Object, Iterable<G>, Collection<G>, Set<G> {
 		assert_not_reached ();
 	}
 
+	public bool add_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool contains_all (Collection<G> collection) {
+		foreach (G element in collection) {
+			if (!contains (element)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public bool remove_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
+	public bool retain_all (Collection<G> collection) {
+		assert_not_reached ();
+	}
+
 	public G[] to_array() {
 		return _set.to_array ();
 	}
diff --git a/gee/treemap.vala b/gee/treemap.vala
index 1c9bb86..a819153 100644
--- a/gee/treemap.vala
+++ b/gee/treemap.vala
@@ -325,6 +325,18 @@ public class Gee.TreeMap<K,V> : Object, Map<K,V> {
 		public override bool contains (K key) {
 			return map.contains (key);
 		}
+
+		public override bool add_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool remove_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool retain_all (Collection<K> collection) {
+			assert_not_reached ();
+		}
 	}
 
 	private class ValueCollection<K,V> : AbstractCollection<V> {
@@ -363,6 +375,18 @@ public class Gee.TreeMap<K,V> : Object, Map<K,V> {
 			}
 			return false;
 		}
+
+		public override bool add_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool remove_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
+
+		public override bool retain_all (Collection<V> collection) {
+			assert_not_reached ();
+		}
 	}
 
 	private class KeyIterator<K,V> : Object, Gee.Iterator<K> {
diff --git a/tests/testarraylist.vala b/tests/testarraylist.vala
index a6d1a97..e842df1 100644
--- a/tests/testarraylist.vala
+++ b/tests/testarraylist.vala
@@ -41,6 +41,11 @@ public class ArrayListTests : CollectionTests {
 		add_test("contains", test_arraylist_contains);
 		add_test("remove", test_arraylist_remove);
 		add_test("size", test_arraylist_size);
+		add_test ("empty", test_arraylist_empty);
+		add_test ("add_all", test_arraylist_add_all);
+		add_test ("contains_all", test_arraylist_contains_all);
+		add_test ("remove_all", test_arraylist_remove_all);
+		add_test ("retain_all", test_arraylist_retain_all);
 
 		// Methods of Iterable interface
 		add_test("iterator", test_arraylist_iterator);
@@ -407,9 +412,6 @@ public class ArrayListTests : CollectionTests {
 	void test_arraylist_remove () {
 		var arraylistOfString = string_collection as Gee.List<string>;
 
-		// Check remove if list is empty
-		arraylistOfString.remove("42");
-
 		// Add 5 same elements
 		arraylistOfString.add ("42");
 		arraylistOfString.add ("42");
@@ -532,6 +534,403 @@ public class ArrayListTests : CollectionTests {
 		assert (iterator.get () == "44");
 		assert (!iterator.next());
 	}
+
+	void test_arraylist_empty () {
+		var arraylist = new ArrayList<int> ();
+
+		// Check empty list
+		assert (arraylist.is_empty);
+
+		// Check when one item
+		arraylist.add (1);
+		assert (!arraylist.is_empty);
+
+		// Check when more items
+		arraylist.add (2);
+		assert (!arraylist.is_empty);
+
+		// Check when items cleared
+		arraylist.clear ();
+		assert (arraylist.is_empty);
+	}
+
+	void test_arraylist_add_all () {
+		var list1 = new ArrayList<int> ();
+		var list2 = new ArrayList<int> ();
+
+		// Check lists empty
+		list1.add_all (list2);
+
+		assert (list1.is_empty);
+		assert (list2.is_empty);
+
+		// Check list1 not empty, list2 is empty
+		list1.add (1);
+		list1.add_all (list2);
+
+		assert (list1.size == 1);
+		assert (list1.contains (1));
+		assert (list2.is_empty);
+
+		list1.clear ();
+		list2.clear ();
+
+		// Check list1 empty, list2 contains 1 element
+		list2.add (1);
+		list1.add_all (list2);
+
+		assert (list1.size == 1);
+		assert (list1.contains (1));
+		assert (list2.size == 1);
+		assert (list2.contains (1));
+
+		list1.clear ();
+		list2.clear ();
+
+		// Check correct order with more elements
+		list1.add (0);
+		list1.add (1);
+		list1.add (2);
+		list2.add (3);
+		list2.add (4);
+		list2.add (5);
+		list1.add_all (list2);
+
+		assert (list1.size == 6);
+		assert (list1.get (0) == 0);
+		assert (list1.get (1) == 1);
+		assert (list1.get (2) == 2);
+		assert (list1.get (3) == 3);
+		assert (list1.get (4) == 4);
+		assert (list1.get (5) == 5);
+
+		assert (list2.size == 3);
+		assert (list2.get (0) == 3);
+		assert (list2.get (1) == 4);
+		assert (list2.get (2) == 5);
+
+		list1.clear ();
+		list2.clear ();
+
+		// Add large collections
+		list1.add (0);
+		list1.add (1);
+		list1.add (2);
+
+		for (int i = 3; i < 103; i++) {
+			list2.add (i);
+		}
+
+		list1.add_all (list2);
+
+		assert (list1.size == 103);
+		assert (list1.get (0) == 0);
+		assert (list1.get (1) == 1);
+		assert (list1.get (2) == 2);
+		assert (list1.get (3) == 3);
+		assert (list1.get (4) == 4);
+		assert (list1.get (99) == 99);
+		assert (list1.get (100) == 100);
+		assert (list1.get (101) == 101);
+		assert (list1.get (102) == 102);
+
+		assert (list2.size == 100);
+
+		list1.clear ();
+		list2.clear ();
+	}
+
+	void test_arraylist_contains_all () {
+		var list1 = new ArrayList<int> ();
+		var list2 = new ArrayList<int> ();
+
+		// Check empty
+		assert (list1.contains_all (list2));
+
+		// list1 has elements, list2 is empty
+		list1.add (1);
+
+		assert (list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+		// list1 is empty, list2 has elements
+		list2.add (1);
+
+		assert (!list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+		// list1 and list2 are the same
+		list1.add (1);
+		list1.add (2);
+		list2.add (1);
+		list1.add (2);
+
+		assert (list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+		// list1 and list2 are the same
+		list1.add (1);
+		list2.add (2);
+
+		assert (!list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+		// list1 has a subset of list2
+		list1.add (1);
+		list1.add (2);
+		list1.add (3);
+		list1.add (4);
+		list1.add (5);
+		list1.add (6);
+
+		list2.add (2);
+		list2.add (4);
+		list2.add (6);
+
+		assert (list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+		// list1 has a subset of in all but one element list2
+		list1.add (1);
+		list1.add (2);
+		list1.add (3);
+		list1.add (4);
+		list1.add (5);
+		list1.add (6);
+
+		list2.add (2);
+		list2.add (4);
+		list2.add (6);
+		list2.add (7);
+
+		assert (!list1.contains_all (list2));
+
+		list1.clear ();
+		list2.clear ();
+
+	}
+
+	void test_arraylist_remove_all () {
+		var arraylist1 = new ArrayList<int> ();
+		var arraylist2 = new ArrayList<int> ();
+
+		// Check empty
+		arraylist1.remove_all (arraylist2);
+		assert (arraylist1.is_empty);
+		assert (arraylist2.is_empty);
+
+		// Arraylist1 and arraylist2 have no common elements -> nothing is removed in arraylist1
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+		arraylist2.add (4);
+		arraylist2.add (5);
+		arraylist2.add (6);
+
+		arraylist1.remove_all (arraylist2);
+
+		assert (arraylist1.size == 3);
+		assert (arraylist2.size == 3);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Arraylist1 and arraylist2 have all elements the same -> everything is removed in arraylist1 but not arraylist2
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+		arraylist2.add (1);
+		arraylist2.add (2);
+		arraylist2.add (3);
+
+		arraylist1.remove_all (arraylist2);
+
+		assert (arraylist1.is_empty);
+		assert (arraylist2.size == 3);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Removing of same elements
+
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+
+		arraylist2.add (1);
+		arraylist2.add (1);
+
+		arraylist1.remove_all (arraylist2);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 2);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+	}
+
+	void test_arraylist_retain_all () {
+		var arraylist1 = new ArrayList<int> ();
+		var arraylist2 = new ArrayList<int> ();
+
+		// Check empty
+
+		assert (arraylist1.is_empty);
+		assert (arraylist2.is_empty);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.is_empty);
+		assert (arraylist2.is_empty);
+
+
+		// Arraylist1 has elements, arraylist2 is empty -> everything in arraylist1 is removed
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+
+		assert (arraylist1.size == 3);
+		assert (arraylist2.size == 0);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 0);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Arraylist1 is empty and arraylist2 has elements -> nothing changes
+		arraylist2.add (4);
+		arraylist2.add (5);
+		arraylist2.add (6);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 3);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 3);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Arraylist1 and arraylist2 have no common elements -> everything is removed in arraylist1
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+		arraylist2.add (4);
+		arraylist2.add (5);
+		arraylist2.add (6);
+
+		assert (arraylist1.size == 3);
+		assert (arraylist2.size == 3);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 3);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Arraylist1 and arraylist2 have all elements the same -> nothing is removed in arraylist1
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+		arraylist2.add (1);
+		arraylist2.add (2);
+		arraylist2.add (3);
+
+		assert (arraylist1.size == 3);
+		assert (arraylist2.size == 3);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 3);
+		assert (arraylist2.size == 3);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Arraylist1 and arraylist2 have 2 common elements but each also has his own elements -> arraylist1 only retains what is in arraylist2
+		arraylist1.add (1);
+		arraylist1.add (2);
+		arraylist1.add (3);
+		arraylist1.add (4);
+		arraylist1.add (5);
+
+		arraylist2.add (0);
+		arraylist2.add (2);
+		arraylist2.add (3);
+		arraylist2.add (7);
+
+		assert (arraylist1.size == 5);
+		assert (arraylist2.size == 4);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 2);
+		assert (arraylist2.size == 4);
+
+		assert (arraylist1.contains (2));
+		assert (arraylist2.contains (3));
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Removing of same elements when arraylist2 has the same element -> nothing changes
+
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+
+		arraylist2.add (1);
+
+		assert (arraylist1.size == 4);
+		assert (arraylist2.size == 1);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 4);
+		assert (arraylist2.size == 1);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+
+		// Removing of same elements when arraylist2 has the NOT same element -> everything is removed
+
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+		arraylist1.add (1);
+
+		arraylist2.add (2);
+
+		assert (arraylist1.size == 4);
+		assert (arraylist2.size == 1);
+
+		arraylist1.retain_all (arraylist2);
+
+		assert (arraylist1.size == 0);
+		assert (arraylist2.size == 1);
+
+		arraylist1.clear ();
+		arraylist2.clear ();
+	}
 }
 
 void main (string[] args) {
diff --git a/tests/testhashset.vala b/tests/testhashset.vala
index 1adff6e..04efeef 100644
--- a/tests/testhashset.vala
+++ b/tests/testhashset.vala
@@ -272,15 +272,392 @@ void test_hashset_iterator () {
 	
 	assert (!iterator.next());
 }
+
+void test_hashset_empty () {
+	var hashset = new HashSet<string> (str_hash, str_equal);
+
+	// Case 1: Check empty set
+	assert (hashset.is_empty);
+
+	// Case 2: Check when one item
+	hashset.add ("1");
+	assert (!hashset.is_empty);
+
+	// Case 3: Check when more items
+	hashset.add ("2");
+	assert (!hashset.is_empty);
+
+	// Case 4: Check when items cleared
+	hashset.clear ();
+	assert (hashset.is_empty);
+}
+
+void test_hashset_add_all () {
+	var hashset1 = new HashSet<string> (str_hash, str_equal);
+	var hashset2 = new HashSet<string> (str_hash, str_equal);
+
+	// Case 1: Check set empty
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.is_empty);
+	assert (hashset2.is_empty);
+
+	// Case 2: Check hashset1 not empty, hashset2 is empty
+	hashset1.add ("1");
+	
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.size == 1);
+	assert (hashset1.contains ("1"));
+	assert (hashset2.is_empty);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 3: Check hashset1 empty, hashset2 contains 1 element
+	hashset2.add ("1");
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.size == 1);
+	assert (hashset1.contains ("1"));
+	assert (hashset2.size == 1);
+	assert (hashset2.contains ("1"));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 4: Check more elements
+	hashset1.add ("0");
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset2.add ("3");
+	hashset2.add ("4");
+	hashset2.add ("5");
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.size == 6);
+	assert (hashset1.contains ("0"));
+	assert (hashset1.contains ("1"));
+	assert (hashset1.contains ("2"));
+	assert (hashset1.contains ("3"));
+	assert (hashset1.contains ("4"));
+	assert (hashset1.contains ("5"));
+
+	assert (hashset2.size == 3);
+	assert (hashset2.contains ("3"));
+	assert (hashset2.contains ("4"));
+	assert (hashset2.contains ("5"));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 5: Check intersecting elements
+	hashset1.add ("0");
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset1.add ("3");
+	hashset2.add ("2");
+	hashset2.add ("3");
+	hashset2.add ("4");
+	hashset2.add ("5");
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.size == 6);
+	assert (hashset1.contains ("0"));
+	assert (hashset1.contains ("1"));
+	assert (hashset1.contains ("2"));
+	assert (hashset1.contains ("3"));
+	assert (hashset1.contains ("4"));
+	assert (hashset1.contains ("5"));
+
+	assert (hashset2.size == 4);
+	assert (hashset2.contains( "2"));
+	assert (hashset2.contains ("3"));
+	assert (hashset2.contains ("4"));
+	assert (hashset2.contains ("5"));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 6: Add large collections
+	hashset1.add ("0");
+	hashset1.add ("1");
+	hashset1.add ("2");
+
+	for(int i = 3; i < 103; i++) {
+		hashset2.add ("%d".printf (i));
+	}
+
+	hashset1.add_all (hashset2);
+
+	assert (hashset1.size == 103);
+	assert (hashset1.contains ("0"));
+	assert (hashset1.contains ("1"));
+	assert (hashset1.contains ("2"));
+	assert (hashset1.contains ("3"));
+	assert (hashset1.contains ("4"));
+	assert (hashset1.contains ("5"));
+	assert (hashset1.contains ("99"));
+	assert (hashset1.contains ("100"));
+	assert (hashset1.contains ("101"));
+	assert (hashset1.contains ("102"));
+
+	assert (hashset2.size == 100);
+
+	hashset1.clear ();
+	hashset2.clear ();
+}
+
+void test_hashset_contains_all () {
+	var hashset1 = new HashSet<string> (str_hash, str_equal);
+	var hashset2 = new HashSet<string> (str_hash, str_equal);
+
+	// Case 1: Check empty
+	assert (hashset1.contains_all (hashset2));
+
+	// Case 2: Hashset1 has elements, hashset2 is empty
+	hashset1.add ("1");
+
+	assert (hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 3: Hashset1 is empty, hashset2 has elements
+	hashset2.add ("1");
+
+	assert (!hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 4: Hashset1 and hashset2 are the same
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset2.add ("1");
+	hashset1.add ("2");
+
+	assert (hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 5: Hashset1 and hashset2 are not the same
+	hashset1.add ("1");
+	hashset2.add ("2");
+
+	assert (!hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 6: Hashset1 has a subset of hashset2
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset1.add ("3");
+	hashset1.add ("4");
+	hashset1.add ("5");
+	hashset1.add ("6");
+
+	hashset2.add ("2");
+	hashset2.add ("4");
+	hashset2.add ("6");
+
+	assert (hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 7: Hashset1 has a subset of hashset2 in all but one element hashset2
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset1.add ("3");
+	hashset1.add ("4");
+	hashset1.add ("5");
+	hashset1.add ("6");
+
+	hashset2.add ("2");
+	hashset2.add ("4");
+	hashset2.add ("6");
+	hashset2.add ("7");
+
+	assert (!hashset1.contains_all (hashset2));
+
+	hashset1.clear ();
+	hashset2.clear ();
+}
+
+void test_hashset_remove_all () {
+	var hashset1 = new HashSet<string> (str_hash, str_equal);
+	var hashset2 = new HashSet<string> (str_hash, str_equal);
+
+	// Case 1: Check empty
+	hashset1.remove_all (hashset2);
+	assert (hashset1.is_empty);
+	assert (hashset2.is_empty);
+
+	// Case 2: Hashset1 and hashset2 have no common elements -> nothing is removed in hashset1
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset1.add ("3");
+	hashset2.add ("4");
+	hashset2.add ("5");
+	hashset2.add ("6");
+
+	hashset1.remove_all (hashset2);
+
+	assert (hashset1.size == 3);
+	assert (hashset1.size == 3);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 3: Hashset1 and hashset2 have all elements the same -> everything is removed in hashset1 but not hashset2
+	hashset1.add ("1");
+	hashset1.add ("2");
+	hashset1.add ("3");
+	hashset2.add ("1");
+	hashset2.add ("2");
+	hashset2.add ("3");
+
+	hashset1.remove_all (hashset2);
+
+	assert (hashset1.is_empty);
+	assert (hashset2.size == 3);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+}
+
+void test_hashset_retain_all () {
+	var hashset1 = new HashSet<int> ();
+	var hashset2 = new HashSet<int> ();
+
+	// Case 1: Check empty
+
+	assert (hashset1.is_empty);
+	assert (hashset2.is_empty);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.is_empty);
+	assert (hashset2.is_empty);
+
+
+	// Case 2: Hashset1 has elements, hashset2 is empty -> everything in hashset1 is removed
+	hashset1.add (1);
+	hashset1.add (2);
+	hashset1.add (3);
+
+	assert (hashset1.size == 3);
+	assert (hashset2.size == 0);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.size == 0);
+	assert (hashset2.size == 0);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 3: Hashset1 is empty and hashset2 has elements -> nothing changes
+	hashset2.add (4);
+	hashset2.add (5);
+	hashset2.add (6);
+
+	assert (hashset1.size == 0);
+	assert (hashset2.size == 3);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.size == 0);
+	assert (hashset2.size == 3);
+
+	hashset1.clear ();
+	hashset2.clear ();
+	
+	// Case 4: Hashset1 and hashset2 have no common elements -> everything is removed in hashset1
+	hashset1.add (1);
+	hashset1.add (2);
+	hashset1.add (3);
+	hashset2.add (4);
+	hashset2.add (5);
+	hashset2.add (6);
+
+	assert (hashset1.size == 3);
+	assert (hashset2.size == 3);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.size == 0);
+	assert (hashset2.size == 3);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 5: Hashset1 and hashset2 have all elements the same -> nothing is removed in hashset1
+	hashset1.add (1);
+	hashset1.add (2);
+	hashset1.add (3);
+	hashset2.add (1);
+	hashset2.add (2);
+	hashset2.add (3);
+
+	assert (hashset1.size == 3);
+	assert (hashset2.size == 3);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.size == 3);
+	assert (hashset2.size == 3);
+
+	hashset1.clear ();
+	hashset2.clear ();
+
+	// Case 6: Hashset1 and hashset2 have 2 common elements but each also has his own elements -> hashset1 only retains what is in hashset2
+	
+	hashset1.add (1);
+	hashset1.add (2);
+	hashset1.add (3);
+	hashset1.add (4);
+	hashset1.add (5);
+
+	hashset2.add (0);
+	hashset2.add (2);
+	hashset2.add (3);
+	hashset2.add (7);
+
+	assert (hashset1.size == 5);
+	assert (hashset2.size == 4);
+
+	hashset1.retain_all (hashset2);
+
+	assert (hashset1.size == 2);
+	assert (hashset2.size == 4);
+
+	assert (hashset1.contains (2));
+	assert (hashset2.contains (3));
+
+	hashset1.clear ();
+	hashset2.clear ();
+}
+
 void main (string[] args) {
 	Test.init (ref args);
 
+	// Methods of Collection interface
 	Test.add_func ("/HashSet/Collection/add", test_hashset_add);
 	Test.add_func ("/HashSet/Collection/clear", test_hashset_clear);
 	Test.add_func ("/HashSet/Collection/contains", test_hashset_contains);
 	Test.add_func ("/HashSet/Collection/remove", test_hashset_remove);
 	Test.add_func ("/HashSet/Collection/size", test_hashset_size);
-	
+	Test.add_func ("/HashSet/Collection/empty", test_hashset_empty);
+	Test.add_func ("/HashSet/Collection/add_all", test_hashset_add_all);
+	Test.add_func ("/HashSet/Collection/contains_all", test_hashset_contains_all);
+	Test.add_func ("/HashSet/Collection/remove_all", test_hashset_remove_all);
+	Test.add_func ("/HashSet/Collection/retain_all", test_hashset_retain_all);
+
 	Test.add_func ("/HashSet/Iterable/iterator", test_hashset_iterator);
 
 	Test.run ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]