[libgee] Refactor testing - do more with less



commit eeecaf687014157190668fd98c1d6cf4b634fff1
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Sun Nov 25 18:34:00 2012 +0000

    Refactor testing - do more with less
    
    Tests had a lot of repetitive code. It was factored out and this allowed
    to test much more cases per run.

 tests/Makefile.am         |    1 +
 tests/testcollection.vala |  383 +++++++++++++++++----------------------------
 tests/testdata.vala       |  111 +++++++++++++
 3 files changed, 252 insertions(+), 243 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 105292e..51bbee1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -13,6 +13,7 @@ tests_SOURCES = \
        testcase.vala \
        testcollection.vala \
        testconcurrentlist.vala \
+       testdata.vala \
        testdeque.vala \
        testfunctions.vala \
        testhashmap.vala \
diff --git a/tests/testcollection.vala b/tests/testcollection.vala
index 2c0050a..ddb9308 100644
--- a/tests/testcollection.vala
+++ b/tests/testcollection.vala
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008  JÃrg Billeter
  * Copyright (C) 2009  Didier Villevalois, Julien Peeters
- * Copyright (C) 2011  Maciej Piechotka
+ * Copyright (C) 2011-2012  Maciej Piechotka
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -73,105 +73,49 @@ public abstract class CollectionTests : Gee.TestCase {
 		assert (! iterator.has_next ());
 		assert (! iterator.next ());
 
+		unowned string[] data = TestData.get_data ();
+
 		// Check for some elements in the collection
-		assert (test_collection.add ("one"));
-		assert (test_collection.add ("two"));
-		assert (test_collection.add ("three"));
+		foreach (unowned string el in data) {
+			assert (test_collection.add (el));
+		}
 
-		bool one_found = false;
-		bool two_found = false;
-		bool three_found = false;
-		bool one_found_once = true;
-		bool two_found_once = true;
-		bool three_found_once = true;
-		iterator = test_collection.iterator ();
-		bool valid = iterator.valid;
-		assert (! valid);
-		while (true) {
-			has_next = iterator.has_next ();
-			assert (valid == iterator.valid);
-			assert (has_next == iterator.next ());
-			assert (valid = iterator.valid);
-			if (! has_next) {
-				break;
+		uint[] found_times = new uint[data.length];
+		for (uint i = 0; i < 2; i++) {
+			for (uint j = 0; j < found_times.length; j++) {
+				found_times[j] = 0;
 			}
-
-			string element = iterator.get ();
-			assert (iterator.valid);
-			if (element == "one") {
-				if (one_found) {
-					one_found_once = false;
-				}
-				one_found = true;
-			} else if (element == "two") {
-				if (two_found) {
-					two_found_once = false;
-				}
-				two_found = true;
-			} else if (element == "three") {
-				if (three_found) {
-					three_found_once = false;
+			iterator = test_collection.iterator ();
+			bool valid = iterator.valid;
+			assert (! valid);
+			while (true) {
+				has_next = iterator.has_next ();
+				assert (valid == iterator.valid);
+				assert (has_next == iterator.next ());
+				assert (valid = iterator.valid);
+				if (! has_next) {
+					break;
 				}
-				three_found = true;
-			}
-		}
-		has_next = iterator.has_next ();
-		assert (! has_next);
-		assert (iterator.valid);
-		assert (has_next == iterator.next ());
-		assert (iterator.valid);
-		assert (one_found);
-		assert (one_found_once);
-		assert (two_found);
-		assert (two_found_once);
-		assert (three_found);
-		assert (three_found_once);
 
-		iterator = test_collection.iterator ();
-		assert (iterator.has_next ());
-		assert (! iterator.valid);
-		assert (iterator.next ());
-
-		one_found = false;
-		two_found = false;
-		three_found = false;
-		one_found_once = true;
-		two_found_once = true;
-		three_found_once = true;
-		while (true) {
-			string element = iterator.get ();
-			if (element == "one") {
-				if (one_found) {
-					one_found_once = false;
-				}
-				one_found = true;
-			} else if (element == "two") {
-				if (two_found) {
-					two_found_once = false;
+				string element = iterator.get ();
+				assert (iterator.valid);
+				for (uint element_idx = 0;; element_idx++) {
+					assert (element_idx < data.length);
+					if (data[element_idx] == element) {
+						found_times[element_idx]++;
+						break;
+					}
 				}
-				two_found = true;
-			} else if (element == "three") {
-				if (three_found) {
-					three_found_once = false;
-				}
-				three_found = true;
 			}
-
 			has_next = iterator.has_next ();
+			assert (! has_next);
+			assert (iterator.valid);
 			assert (has_next == iterator.next ());
-			if (! has_next) {
-				break;
+			assert (iterator.valid);
+			foreach (var ft in found_times) {
+				assert (ft == 1);
 			}
 		}
-		has_next = iterator.has_next ();
-		assert (! has_next);
-		assert (has_next == iterator.next ());
-		assert (one_found);
-		assert (one_found_once);
-		assert (two_found);
-		assert (two_found_once);
-		assert (three_found);
-		assert (three_found_once);
 	}
 
 	public void test_mutable_iterator () {
@@ -183,172 +127,143 @@ public abstract class CollectionTests : Gee.TestCase {
 		Iterator<string> iterator = test_collection.iterator ();
 		// ...
 
-		// Check for some elements in the collection and remove one
-		assert (test_collection.add ("one"));
-		assert (test_collection.add ("two"));
-		assert (test_collection.add ("three"));
+		unowned string[] data = TestData.get_data ();
+		unowned uint[] idx = TestData.get_drawn_numbers ();
 
-		bool one_found = false;
-		bool two_found = false;
-		bool three_found = false;
-		bool one_found_once = true;
-		bool two_found_once = true;
-		bool three_found_once = true;
-		iterator = test_collection.iterator ();
-		while (true) {
-			has_next = iterator.has_next ();
-			assert (has_next == iterator.next ());
-			if (! has_next) {
-				break;
-			}
-			assert (iterator.valid);
-
-			string element = iterator.get ();
-			if (element == "one") {
-				if (one_found) {
-					one_found_once = false;
-				}
-				one_found = true;
-			} else if (element == "two") {
-				if (two_found) {
-					two_found_once = false;
-				}
-				two_found = true;
-
-				// Remove this element
-				assert (! iterator.read_only);
-				iterator.remove ();
-				assert (! iterator.valid);
-			} else if (element == "three") {
-				if (three_found) {
-					three_found_once = false;
-				}
-				three_found = true;
-			}
+		// Check for some elements in the collection and remove few
+		foreach (unowned string el in data) {
+			assert (test_collection.add (el));
 		}
-		has_next = iterator.has_next ();
-		assert (! has_next);
-		assert (has_next == iterator.next ());
-		assert (one_found);
-		assert (one_found_once);
-		assert (two_found);
-		assert (two_found_once);
-		assert (three_found);
-		assert (three_found_once);
-
-		// Check after removal
+
 		iterator = test_collection.iterator ();
-		assert (iterator.has_next ());
-		assert (iterator.next ());
-
-		one_found = false;
-		two_found = false;
-		three_found = false;
-		one_found_once = true;
-		two_found_once = true;
-		three_found_once = true;
-		while (true) {
-			string element = iterator.get ();
-			if (element == "one") {
-				if (one_found) {
-					one_found_once = false;
+		uint[] found_times = new uint[data.length];
+		for (uint i = 0; i <= idx.length; i++) {
+			for (uint j = 0; j < found_times.length; j++) {
+				found_times[j] = 0;
+			}
+			iterator = test_collection.iterator ();
+			assert (! iterator.valid);
+			bool last_removed = false;
+			while (true) {
+				has_next = iterator.has_next ();
+				assert (has_next == iterator.next ());
+				if (! has_next) {
+					break;
 				}
-				one_found = true;
-			} else if (element == "two") {
-				two_found = true;
-			} else if (element == "three") {
-				if (three_found) {
-					three_found_once = false;
+
+				string element = iterator.get ();
+				assert (iterator.valid);
+				for (uint element_idx = 0;; element_idx++) {
+					assert (element_idx < data.length);
+					if (data[element_idx] == element) {
+						if (i != idx.length && data[element_idx] == data[idx[i]]) {
+							iterator.remove ();
+							assert (! iterator.valid);
+							last_removed = true;
+						} else {
+							last_removed = false;
+						}
+						found_times[element_idx]++;
+						break;
+					}
 				}
-				three_found = true;
 			}
-
 			has_next = iterator.has_next ();
+			assert (! has_next);
+			assert (iterator.valid == !last_removed);
 			assert (has_next == iterator.next ());
-			if (! has_next) {
-				break;
+			assert (iterator.valid == !last_removed);
+			for (uint j = 0; j < found_times.length; j++) {
+				bool removed = false;
+				for (int k = 0; k < i; k++) {
+					if (idx[k] == j) {
+						removed = true;
+						break;
+					}
+				}
+				assert (found_times[j] == (removed ? 0 : 1));
 			}
 		}
-		has_next = iterator.has_next ();
-		assert (! has_next);
-		assert (has_next == iterator.next ());
-		assert (one_found);
-		assert (one_found_once);
-		assert (!two_found);
-		assert (three_found);
-		assert (three_found_once);
 	}
 
 	public void test_contains_size_and_is_empty () {
 		// Check the collection exists
 		assert (test_collection != null);
 
+		unowned string[] data = TestData.get_data ();
+		unowned uint[] idx = TestData.get_drawn_numbers ();
+
 		// Check the collection is initially empty
-		assert (! test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
+		foreach (unowned string s in data) {
+			assert (! test_collection.contains (s));
+		}
 		assert (test_collection.size == 0);
 		assert (test_collection.is_empty);
 
 		// Add an element
-		assert (test_collection.add ("one"));
-		assert (test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
+		assert (test_collection.add (data[0]));
+		assert (test_collection.contains (data[0]));
+		for (uint i = 1; i < data.length; i++) {
+			assert (! test_collection.contains (data[i]));
+		}
 		assert (test_collection.size == 1);
 		assert (! test_collection.is_empty);
 
 		// Remove the added element
 		assert (test_collection.remove ("one"));
-		assert (! test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
+		foreach (unowned string s in data) {
+			assert (! test_collection.contains (s));
+		}
 		assert (test_collection.size == 0);
 		assert (test_collection.is_empty);
 
 		// Add more elements
-		assert (test_collection.add ("one"));
-		assert (test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
-		assert (test_collection.size == 1);
-		assert (! test_collection.is_empty);
-
-		assert (test_collection.add ("two"));
-		assert (test_collection.contains ("one"));
-		assert (test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
-		assert (test_collection.size == 2);
-		assert (! test_collection.is_empty);
-
-		assert (test_collection.add ("three"));
-		assert (test_collection.contains ("one"));
-		assert (test_collection.contains ("two"));
-		assert (test_collection.contains ("three"));
-		assert (test_collection.size == 3);
-		assert (! test_collection.is_empty);
-
-		// Remove one element
-		assert (test_collection.remove ("two"));
-		assert (test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (test_collection.contains ("three"));
-		assert (test_collection.size == 2);
-		assert (! test_collection.is_empty);
-
-		// Remove the same element again
-		assert (! test_collection.remove ("two"));
-		assert (test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (test_collection.contains ("three"));
-		assert (test_collection.size == 2);
-		assert (! test_collection.is_empty);
+		for (uint i = 0; i < data.length; i++) {
+			assert (test_collection.add (data[i]));
+			for (uint j = 0; j <= i; j++) {
+				assert (test_collection.contains (data[j]));
+			}
+			for (uint j = i + 1; j < data.length; j++) {
+				assert (! test_collection.contains (data[j]));
+			}
+			assert (test_collection.size == i + 1);
+			assert (! test_collection.is_empty);
+		}
+		for (uint i = 0; i < idx.length; i++) {
+			// Remove one element
+			assert (test_collection.remove (data[idx[i]]));
+			for (uint j = 0; j < data.length; j++) {
+				bool removed = false;
+				for (uint k = 0; k <= i; k++) {
+					if (idx[k] == j) {
+						removed = true;
+						break;
+					}
+				}
+				assert (test_collection.contains (data[j]) == !removed);
+			}
+			assert (test_collection.size == data.length - (i + 1));
+
+			// Remove the same element again
+			assert (! test_collection.remove (data[idx[i]]));
+			for (uint j = 0; j < data.length; j++) {
+				bool removed = false;
+				for (uint k = 0; k <= i; k++) {
+					if (idx[k] == j) {
+						removed = true;
+						break;
+					}
+				}
+				assert (test_collection.contains (data[j]) == !removed);
+			}
+			assert (test_collection.size == data.length - (i + 1));
+		}
 
 		// Remove all elements
 		test_collection.clear ();
-		assert (! test_collection.contains ("one"));
-		assert (! test_collection.contains ("two"));
-		assert (! test_collection.contains ("three"));
+		foreach (unowned string el in data) {
+			assert (! test_collection.contains (el));
+		}
 		assert (test_collection.size == 0);
 		assert (test_collection.is_empty);
 	}
@@ -357,16 +272,7 @@ public abstract class CollectionTests : Gee.TestCase {
 		// Check the collection exists
 		assert (test_collection != null);
 
-		string[] to_add = {
-			"one", "two", "three", "four", "five", "six", "seven", "eight",
-			"nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
-			"fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
-			"twenty one", "twenty two", "twenty three", "twenty four",
-			"twenty five", "twenty six", "twenty seven", "twenty eight",
-			"twenty nine", "thirty", "thirty one", "thirty two", "thirty four",
-			"thirty five", "thirty six", "thirty seven", "thirty eight",
-			"thirty nine", "fourty"
-		};
+		unowned string[] to_add = TestData.get_data ();
 		var expected_size = 0;
 
 		foreach (var a in to_add) {
@@ -394,16 +300,7 @@ public abstract class CollectionTests : Gee.TestCase {
 		// Check the collection exists
 		assert (test_collection != null);
 
-		string[] to_add = {
-			"one", "two", "three", "four", "five", "six", "seven", "eight",
-			"nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
-			"fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty",
-			"twenty one", "twenty two", "twenty three", "twenty four",
-			"twenty five", "twenty six", "twenty seven", "twenty eight",
-			"twenty nine", "thirty", "thirty one", "thirty two", "thirty four",
-			"thirty five", "thirty six", "thirty seven", "thirty eight",
-			"thirty nine", "fourty"
-		};
+		unowned string[] to_add = TestData.get_data ();
 		var expected_size = 0;
 
 		foreach (var a in to_add) {
diff --git a/tests/testdata.vala b/tests/testdata.vala
new file mode 100644
index 0000000..5f00c97
--- /dev/null
+++ b/tests/testdata.vala
@@ -0,0 +1,111 @@
+/* testcollection.vala
+ *
+ * Copyright (C) 2012  Maciej Piechotka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *      Maciej Piechotka <uzytkownik2 gmail com>
+ */
+public class TestData {
+	private static string?[] ones = {null, "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
+	private static string[] tens = {null, null, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
+	private static string hundred = "hundred";
+	private static string?[] thousands = {null, "thousand", "million", "billion", "trillion"};
+
+	private static uint data_size () {
+		return Test.quick() ? 128 : 1024;
+	}
+
+	private static uint DATA_SIZE = data_size ();
+	private static const uint RND_IDX_SIZE = 8;
+
+	private static string[] data = create_data (DATA_SIZE);
+	private static string[] sorted_data = sort_array (data);
+	private static uint[] random_idx = draw_numbers(DATA_SIZE, RND_IDX_SIZE);
+
+	public static unowned string[] get_data () {
+		TypeClass klass = typeof (TestData).class_ref ();
+		klass.get_type ();
+		return data;
+	}
+
+	public static unowned string[] get_sorted_data () {
+		TypeClass klass = typeof (TestData).class_ref ();
+		klass.get_type ();
+		return sorted_data;
+	}
+
+	public static unowned uint[] get_drawn_numbers () {
+		TypeClass klass = typeof (TestData).class_ref ();
+		klass.get_type ();
+		return random_idx;
+	}
+
+	private static uint[] draw_numbers (uint n, uint k) {
+		uint[] result = new uint[n];
+		// Initialize array
+		for (uint i = 0; i < n; i++) {
+			result[i] = i;
+		}
+		// Fisher-Yates shuffle algorithm. Possibly not the most efficient implementation but oh well
+		for (uint i = n - 1; i >= 1; i--) {
+			int j = Test.rand_int_range (0, (int32)(i + 1));
+			uint tmp = result[i];
+			result[i] = result[j];
+			result[j] = tmp;
+		}
+		result.resize ((int)k);
+		return (owned)result;
+	}
+
+	private static string print3digit (uint n) {
+		string? h = (n >= 200) ? "%s %s".printf(ones[n / 100], hundred) : ((n >= 100) ? hundred : null);
+		n = n % 100;
+		unowned string? t = tens[n / 10];
+		n = (n >= ones.length) ? n % 10 : n;
+		unowned string? o = ones[n];
+		return "%s%s%s%s%s".printf(h != null ? h : "", h != null && (t != null || o != null) ? " " : "", t != null ? t : "", t != null && o != null ? "-" : "", o != null ? o : "");
+	}
+
+	private static string[] create_data (uint count) {
+		string[] numbers = new string[count];
+		for (uint idx = 0; idx < count; idx++) {
+			uint n = idx + 1;
+			string? num = null;
+			uint th = 0;
+			while (n != 0) {
+				if (n % 1000 != 0) {
+					string? t = thousands[th];
+					string c = print3digit (n % 1000);
+					num = "%s%s%s%s%s".printf(c, t != null ? " " : "", t != null ? t : "", num != null ? " " : "", num != null ? num : "");
+				}
+				n /= 1000;
+				th++;
+			}
+			if (num == null) {
+				num = "zero";
+			}
+			numbers[idx] = (owned)num;
+		}
+		return (owned)numbers;
+	}
+
+	private static string[] sort_array (owned string[] array) {
+		qsort_with_data<string> (array, sizeof(string), (a, b) => {return strcmp(*(string **)a, *(string **)b);});
+		return (owned)array;
+	}
+}
+



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