//  Copyright © 2015 Rob Rix. All rights reserved.

final class ListTests: XCTestCase {
	func testModuleTypechecks() {
		module.typecheck().forEach { XCTFail($0) }
	}

	func testAutomaticallyEncodedDefinitionsAreEquivalentToHandEncodedDefinitions() {
		expected.definitions.forEach { symbol, type, value in
			assert(module.context[symbol], ==, type, message: "'\(symbol)' expected '\(type)', actual '\(module.context[symbol])'")
			assert(module.environment[symbol], ==, value, message: "'\(symbol)' expected '\(value)', actual '\(module.environment[symbol])'")
		}
	}

	func testTypeOfConsIsParameterizedByAType() {
		assert(module.context["cons"], ==, .lambda(.Type, { A in .lambda(A, const(.lambda(.Application("List", A), const(.Application("List", A))))) }))
	}
}

private let module = Module<Term>.list
private let expected: Module<Term> = {
	let List: Term = "List"
	let list = Declaration("List",
		type: .Type --> .Type,
		value: (.Type, .Type) => { A, B in (A --> List[A] --> B) --> B --> B })

	let cons = Declaration("cons",
		type: .Type => { A in A --> List[A] --> List[A] },
		value: .Type => { (A: Term) in (A, List[A], .Type) => { head, tail, B in (A --> List[A] --> B, B) => { ifCons, _ in ifCons[head, tail] } } })

	let `nil` = Declaration("nil",
		type: .Type => { (A: Term) in List[A] },
		value: (.Type, .Type) => { A, B in (A --> List[A] --> B, B) => { _, other in other } })

	return Module("ChurchList", [ list, cons, `nil` ])
}()


import Assertions
@testable import Manifold
import Prelude
import XCTest

//  Copyright © 2015 Rob Rix. All rights reserved.

final class ListTests: XCTestCase {
	func testModuleTypechecks() {
		module.typecheck().forEach { XCTFail($0) }
	}

	func testTypeOfConsIsParameterizedByAType() {
		assert(module.context["cons"], ==, .lambda(.Type, { A in .lambda(A, const(.lambda(.Application("List", A), const(.Application("List", A))))) }))
	}
}

private let module = Module<Term>.list


import Assertions
@testable import Manifold
import Prelude
import XCTest

--- 
+++ 
@@ -3,6 +3,13 @@
 final class ListTests: XCTestCase {
 	func testModuleTypechecks() {
 		module.typecheck().forEach { XCTFail($0) }
+	}
+
+	func testAutomaticallyEncodedDefinitionsAreEquivalentToHandEncodedDefinitions() {
+		expected.definitions.forEach { symbol, type, value in
+			assert(module.context[symbol], ==, type, message: "'\(symbol)' expected '\(type)', actual '\(module.context[symbol])'")
+			assert(module.environment[symbol], ==, value, message: "'\(symbol)' expected '\(value)', actual '\(module.environment[symbol])'")
+		}
 	}
 
 	func testTypeOfConsIsParameterizedByAType() {
@@ -11,6 +18,22 @@
 }
 
 private let module = Module<Term>.list
+private let expected: Module<Term> = {
+	let List: Term = "List"
+	let list = Declaration("List",
+		type: .Type --> .Type,
+		value: (.Type, .Type) => { A, B in (A --> List[A] --> B) --> B --> B })
+
+	let cons = Declaration("cons",
+		type: .Type => { A in A --> List[A] --> List[A] },
+		value: .Type => { (A: Term) in (A, List[A], .Type) => { head, tail, B in (A --> List[A] --> B, B) => { ifCons, _ in ifCons[head, tail] } } })
+
+	let `nil` = Declaration("nil",
+		type: .Type => { (A: Term) in List[A] },
+		value: (.Type, .Type) => { A, B in (A --> List[A] --> B, B) => { _, other in other } })
+
+	return Module("ChurchList", [ list, cons, `nil` ])
+}()
 
 
 import Assertions
Test List against hand-encoded expectations.
