class Test { BoardSpec spec def check def Test(String spec) { this(new BoardSpec(spec)) } def Test(String spec, check) { this(new BoardSpec(spec), check) } def Test(BoardSpec spec) { this(spec, { it.isSolved() }) } def Test(BoardSpec spec, check) { this.spec = spec this.check = check } } class TestRunner { Solver solver def TestRunner(solver) { this.solver = solver } boolean test() { test(solver.strategies*.getClass()) } boolean test(strategy) { test([strategy]) } boolean test(Collection strategies) { def total = strategies.sum(0) { it.tests.size() } def count = 0 strategies.each { type -> println '-' * 81 println "- $type.name" println '-' * 81 type.tests.eachWithIndex { it, i -> def board = it.spec.board solver.board = board try { println "test ${i + 1}/${type.tests.size()} (${++count}/$total)" println board.spec def startTime = System.currentTimeMillis() if (solver.solveEnough(it.check)) { println board.spec println "passed! (${System.currentTimeMillis() - startTime} ms)" } else { println board.spec throw new IllegalStateException("Test ${i + 1} for strategy $type.name failed (${System.currentTimeMillis() - startTime} ms)") } } catch (RuntimeException re) { println board.toDetailString() throw re } println() } } true } }