Skip to content

Commit

Permalink
Some tidy up to do but this is essentially opentest4j done
Browse files Browse the repository at this point in the history
Fixes #34
Fixes #31
  • Loading branch information
robfletcher committed May 19, 2018
1 parent fc707c7 commit 3db0a5b
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 163 deletions.
19 changes: 15 additions & 4 deletions samples/src/test/kotlin/strikt/samples/DiffFormatting.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,20 @@ internal object DiffFormatting {
@Test
fun formatsBlockDiffInIntelliJ() {
assertThrows<MultipleFailuresError> {
expect("Expect that: %s", "o hai") {
expect("Expect that %s", "o hai") {
isEqualTo("kthxbye")
isEqualTo("o HAi")
}
}.let {
assertEquals(
"Expect that \"o hai\" (2 failures)\n" +
"\tis equal to \"kthxbye\"\n" +
"\tis equal to \"o HAi\"",
it.message
)
assertEquals(2, it.failures.size)
assertEquals("is equal to \"kthxbye\"", it.failures[0].message)
assertEquals("is equal to \"o HAI\"", it.failures[1].message)
assertEquals("is equal to \"kthxbye\"", it.failures[0].message)
assertEquals("is equal to \"o HAi\"", it.failures[1].message)
}
}

Expand All @@ -28,8 +34,13 @@ internal object DiffFormatting {
assertThrows<MultipleFailuresError> {
expect("o hai").isEqualTo("o HAi")
}.let {
assertEquals(
"Expect that \"o hai\" (1 failure)\n" +
"\tis equal to \"o HAi\"",
it.message
)
assertEquals(1, it.failures.size)
assertEquals("is equal to \"o HAi\"", it.failures[0].message)
assertEquals("is equal to \"o HAi\"", it.failures[0].message)
}
}
}
8 changes: 4 additions & 4 deletions strikt-core/src/main/kotlin/strikt/api/Assertion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package strikt.api

import strikt.api.reporting.Result
import strikt.api.reporting.Subject
import strikt.opentest4j.toError
import strikt.opentest4j.throwOnFailure
import kotlin.jvm.internal.CallableReference

/**
Expand Down Expand Up @@ -129,7 +129,7 @@ internal constructor(
if (assertion.negated) {
result.fail()
if (assertion.mode == Mode.FAIL_FAST) {
throw assertion.subject.root.toError()
assertion.subject.throwOnFailure()
}
} else {
result.pass()
Expand All @@ -142,7 +142,7 @@ internal constructor(
} else {
result.fail()
if (assertion.mode == Mode.FAIL_FAST) {
throw assertion.subject.root.toError()
assertion.subject.throwOnFailure()
}
}
}
Expand All @@ -153,7 +153,7 @@ internal constructor(
} else {
result.fail(actual)
if (assertion.mode == Mode.FAIL_FAST) {
throw assertion.subject.root.toError()
assertion.subject.throwOnFailure()
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions strikt-core/src/main/kotlin/strikt/api/Expect.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package strikt.api

import strikt.api.reporting.Subject
import strikt.assertions.throws
import strikt.opentest4j.toError
import strikt.opentest4j.throwOnFailure

/**
* Start a chain of assertions over [subject].
Expand Down Expand Up @@ -56,11 +56,9 @@ fun <T> expect(
): Assertion<T> {
return Subject(subjectDescription, subject)
.let {
val assertion = Assertion(it, Mode.COLLECT).apply(block)
if (it.anyFailed) {
throw it.toError()
} else {
assertion
Assertion(it, Mode.COLLECT).apply {
block()
it.throwOnFailure()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,4 @@ internal open class DefaultResultWriter : ResultWriter {
protected open fun writeSubjectIcon(writer: Appendable) {
writer.append("")
}

protected open fun formatValue(value: Any?): Any =
when (value) {
null -> "null"
is CharSequence -> "\"$value\""
is Char -> "'$value'"
is Iterable<*> -> value.map(this::formatValue)
is Class<*> -> value.name
is Regex -> "/${value.pattern}/"
else -> value
}
}
}
12 changes: 12 additions & 0 deletions strikt-core/src/main/kotlin/strikt/api/reporting/Formatting.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package strikt.api.reporting

fun formatValue(value: Any?): Any =
when (value) {
null -> "null"
is CharSequence -> "\"$value\""
is Char -> "'$value'"
is Iterable<*> -> value.map(::formatValue)
is Class<*> -> value.name
is Regex -> "/${value.pattern}/"
else -> value
}
34 changes: 28 additions & 6 deletions strikt-core/src/main/kotlin/strikt/opentest4j/Errors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,36 @@ package strikt.opentest4j

import org.opentest4j.AssertionFailedError
import org.opentest4j.MultipleFailuresError
import org.opentest4j.TestSkippedException
import strikt.api.Status.Failed
import strikt.api.Status.Pending
import strikt.api.reporting.Reportable
import strikt.api.reporting.Result
import strikt.api.reporting.writeToString
import strikt.api.reporting.Subject
import strikt.api.reporting.formatValue

fun Reportable.toError(): Throwable {
return if (this is Result && results.isEmpty()) {
AssertionFailedError(writeToString(), expected, actual)
} else {
MultipleFailuresError(writeToString(), results.map { it.toError() })
fun Reportable.throwOnFailure() {
root.toError()?.let { throw it }
}

fun Reportable.toError(): Throwable? {
return when (this) {
is Result -> {
when (status) {
Failed -> if (results.isEmpty()) {
AssertionFailedError(description.format(formatValue(expected), formatValue(actual)), expected, actual)
} else {
MultipleFailuresError(description.format(formatValue(expected), formatValue(actual)), results.mapNotNull { it.toError() })
}
Pending -> TestSkippedException(description.format(formatValue(expected), formatValue(actual)))
else -> null
}
}
is Subject<*> ->
when (status) {
Failed -> MultipleFailuresError(description.format(formatValue(value)), results.mapNotNull { it.toError() })
Pending -> TestSkippedException(description.format(formatValue(value)))
else -> null
}
}
}
16 changes: 7 additions & 9 deletions strikt-core/src/test/kotlin/strikt/Mapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,9 @@ internal object Mapping : Spek({
expect(subject).map(Person::name).isEqualTo("Ziggy")
}.let { e ->
val expectedMessage = listOf(
"▼ Expect that Person(name=David, birthDate=1947-01-08)",
" ▼ .name \"${subject.name}\"",
" ✗ is equal to Ziggy",
""
"Expect that Person(name=David, birthDate=1947-01-08) (1 failure)",
"\t.name \"${subject.name}\" (1 failure)",
"\tis equal to \"Ziggy\""
)
assertEquals(expectedMessage, e.message?.lines())
}
Expand All @@ -79,11 +78,10 @@ internal object Mapping : Spek({
expect(subject).map(Person::birthDate).map(LocalDate::getYear).isEqualTo(1971)
}.let { e ->
val expectedMessage = listOf(
"▼ Expect that Person(name=David, birthDate=1947-01-08)",
" ▼ .birthDate ${subject.birthDate}",
" ▼ .year ${subject.birthDate.year}",
" ✗ is equal to 1971",
""
"Expect that Person(name=David, birthDate=1947-01-08) (1 failure)",
"\t.birthDate ${subject.birthDate} (1 failure)",
"\t.year ${subject.birthDate.year} (1 failure)", // TODO: can we make it indent again?
"\tis equal to 1971"
)
assertEquals(expectedMessage, e.message?.lines())
}
Expand Down
111 changes: 33 additions & 78 deletions strikt-core/src/test/kotlin/strikt/Reporting.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,92 +22,47 @@ object Reporting : Spek({
.all { startsWith('c') }
}

// it("reports assertion statistics") {
// assertEquals(3, e.assertionCount, "Assertions")
// assertEquals(0, e.passCount, "Passed")
// assertEquals(3, e.failureCount, "Failed")
// }

it("formats the error message") {
val expectedLines = listOf(
"▼ Expect that [\"catflap\", \"rubberplant\", \"marzipan\"]",
" ✓ has size 3",
" ✗ all elements match:",
" ▼ Expect that \"catflap\"",
" ✗ is upper case",
" ▼ Expect that \"rubberplant\"",
" ✗ is upper case",
" ▼ Expect that \"marzipan\"",
" ✗ is upper case",
""
)
val actualLines = e.message?.lines() ?: emptyList()
assertEquals(
expectedLines.size,
actualLines.size,
"Expected ${expectedLines.size} lines of output but found ${actualLines.size}"
)
actualLines.forEachIndexed { i, line ->
assertEquals(
expectedLines[i],
line,
"Assertion failure message line ${i + 1}"
)
}
val expected =
"Expect that [\"catflap\", \"rubberplant\", \"marzipan\"] (1 failure)\n" +
"\tall elements match: (3 failures)\n" +
"\tExpect that \"catflap\" (1 failure)\n" +
"\tis upper case\n" +
"\tExpect that \"rubberplant\" (1 failure)\n" +
"\tis upper case\n" +
"\tExpect that \"marzipan\" (1 failure)\n" +
"\tis upper case"
assertEquals(expected, e.message)
}
}
}

on("evaluating a block assertion with multiple failures") {
on("evaluating a block assertion with multiple failures") {

val e = fails {
val subject = setOf("catflap", "rubberplant", "marzipan")
expect(subject) {
hasSize(0)
all {
isUpperCase()
startsWith('c')
}
val e = fails {
val subject = setOf("catflap", "rubberplant", "marzipan")
expect(subject) {
hasSize(0)
all {
isUpperCase()
startsWith('c')
}
}
}

// it("reports assertion statistics") {
// assertEquals(7, e.assertionCount, "Assertions")
// assertEquals(1, e.passCount, "Passed")
// assertEquals(6, e.failureCount, "Failed")
// }

it("formats the error message") {
val expectedLines = listOf(
"▼ Expect that [\"catflap\", \"rubberplant\", \"marzipan\"]",
" ✗ has size 0",
" • found 3",
" ✗ all elements match:",
" ▼ Expect that \"catflap\"",
" ✗ is upper case",
" ✓ starts with 'c'",
" ▼ Expect that \"rubberplant\"",
" ✗ is upper case",
" ✗ starts with 'c'",
" ▼ Expect that \"marzipan\"",
" ✗ is upper case",
" ✗ starts with 'c'",
""
)
val actualLines = e.message?.lines() ?: emptyList()
assertEquals(
expectedLines.size,
actualLines.size,
"Expected ${expectedLines.size} lines of output but found ${actualLines.size}"
)
actualLines.forEachIndexed { i, line ->
assertEquals(
expectedLines[i],
line,
"Assertion failure message line ${i + 1}"
)
}
}
it("formats the error message") {
val expected = "Expect that [\"catflap\", \"rubberplant\", \"marzipan\"] (2 failures)\n" +
"\thas size 0\n" +
"\tall elements match: (3 failures)\n" +
"\tExpect that \"catflap\" (1 failure)\n" +
"\tis upper case\n" +
"\tExpect that \"rubberplant\" (2 failures)\n" +
"\tis upper case\n" +
"\tstarts with 'c'\n" +
"\tExpect that \"marzipan\" (2 failures)\n" +
"\tis upper case\n" +
"\tstarts with 'c'"
assertEquals(expected, e.message)
}
}

})
Loading

0 comments on commit 3db0a5b

Please sign in to comment.