diff --git a/build.xml b/build.xml
index 68287f6f74f..b5931e595ce 100644
--- a/build.xml
+++ b/build.xml
@@ -61,6 +61,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -77,6 +98,9 @@
+
+
+
@@ -172,7 +196,7 @@
-
+
@@ -212,7 +236,7 @@
-
+
diff --git a/kunit/kunit.iml b/kunit/kunit.iml
new file mode 100644
index 00000000000..3f40ca246b5
--- /dev/null
+++ b/kunit/kunit.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/kunit/lib/junit-4.9.jar b/kunit/lib/junit-4.9.jar
new file mode 100644
index 00000000000..14208156115
Binary files /dev/null and b/kunit/lib/junit-4.9.jar differ
diff --git a/kunit/module.kt b/kunit/module.kt
new file mode 100644
index 00000000000..7b6de7bf721
--- /dev/null
+++ b/kunit/module.kt
@@ -0,0 +1,10 @@
+import kotlin.modules.*
+
+fun project() {
+ module("kunit") {
+ // TODO how to refer to the dir of the module?
+ classpath += "kunit/lib/junit-4.9.jar"
+
+ addSourceFiles("src/main/kotlin")
+ }
+}
\ No newline at end of file
diff --git a/kunit/src/main/kotlin/Test.kt b/kunit/src/main/kotlin/Test.kt
new file mode 100644
index 00000000000..2ce0fb64375
--- /dev/null
+++ b/kunit/src/main/kotlin/Test.kt
@@ -0,0 +1,100 @@
+/**
+ * A number of helper methods for writing Kool unit tests
+ */
+package kool.test
+
+import org.junit.Assert
+
+/** Asserts that the given block returns true */
+fun assert(message: String, block: ()-> Boolean) {
+ val actual = block()
+ Assert.assertTrue(message, actual)
+}
+
+/** Asserts that the given block returns true */
+fun assert(block: ()-> Boolean) = assert(block.toString(), block)
+
+/** Asserts that the given block returns false */
+fun assertNot(message: String, block: ()-> Boolean) {
+ assert(message){ !block() }
+}
+
+/** Asserts that the given block returns true */
+fun assertNot(block: ()-> Boolean) = assertNot(block.toString(), block)
+
+/** Asserts that the expression is true with an optional message */
+fun assert(actual: Boolean, message: String = "") {
+ assertTrue(actual, message)
+}
+
+/** Asserts that the expression is true with an optional message */
+fun assertTrue(actual: Boolean, message: String = "") {
+ return assertEquals(true, actual, message)
+}
+
+/** Asserts that the expression is false with an optional message */
+fun assertFalse(actual: Boolean, message: String = "") {
+ return assertEquals(false, actual, message)
+}
+
+/** Asserts that the expected value is equal to the actual value, with an optional message */
+fun assertEquals(expected: Any?, actual: Any?, message: String = "") {
+ Assert.assertEquals(message, expected, actual)
+}
+
+/** Asserts that the expression is not null, with an optional message */
+fun assertNotNull(actual: Any?, message: String = "") {
+ Assert.assertNotNull(message, actual)
+}
+
+/** Asserts that the expression is null, with an optional message */
+fun assertNull(actual: Any?, message: String = "") {
+ Assert.assertNull(message, actual)
+}
+
+/** Marks a test as having failed if this point in the execution path is reached, with an optional message */
+fun fail(message: String = "") {
+ Assert.fail(message)
+}
+
+/** Asserts that given function block returns the given expected value */
+fun expect(expected: T, block: ()-> T) {
+ expect(expected, block.toString(), block)
+}
+
+/** Asserts that given function block returns the given expected value and use the given message if it fails */
+fun expect(expected: T, message: String, block: ()-> T) {
+ val actual = block()
+ assertEquals(expected, actual, message)
+}
+
+/** Asserts that given function block fails by throwing an exception */
+fun fails(block: ()-> Any): Exception? {
+ try {
+ block()
+ Assert.fail("Expected an exception to be thrown")
+ return null
+ } catch (e: Exception) {
+ println("Caught excepted exception: $e")
+ return e
+ }
+}
+
+/** Asserts that a block fails with a specific exception being thrown */
+fun failsWith(block: ()-> Any) {
+ try {
+ block()
+ Assert.fail("Expected an exception to be thrown")
+ } catch (e: T) {
+ println("Caught excepted exception: $e")
+ // OK
+ }
+}
+
+/**
+ * Comments out a block of test code until it is implemented while keeping a link to the code
+ * to implement in your unit test output
+ */
+fun todo(block: ()-> Any) {
+ println("TODO at " + (Exception() as java.lang.Throwable).getStackTrace()?.get(1) + " for " + block)
+}