Skip to content

Commit

Permalink
Merge pull request #27 from raniejade/group-tagging
Browse files Browse the repository at this point in the history
Implement focused and pending groups
  • Loading branch information
raniejade committed Apr 16, 2016
2 parents 6531840 + 607f2ff commit 8c6a66e
Show file tree
Hide file tree
Showing 31 changed files with 710 additions and 228 deletions.
13 changes: 7 additions & 6 deletions kspec-core/src/main/kotlin/io/polymorphicpanda/kspec/KSpec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ abstract class KSpec: Spec {

open fun configure(config: KSpecConfig) {}

override fun group(description: String, block: () -> Unit) {
override fun group(description: String, tags: Set<Tag>, block: () -> Unit) {
invokeIfNotDisabled {
val context = ExampleGroupContext(description, current)
val context = ExampleGroupContext(description, current, tags)
current = context
block()
current = current.parent ?: current
Expand Down Expand Up @@ -60,13 +60,14 @@ abstract class KSpec: Spec {
}
}

override fun <T: Any> group(subject: KClass<T>, description: String, block: SubjectSpec<T>.() -> Unit) {
override fun <T: Any> group(subject: KClass<T>, description: String, tags: Set<Tag>,
block: SubjectSpec<T>.() -> Unit) {
invokeIfNotDisabled {
val context = ExampleGroupContext(description.format(subject), current) {
val context = ExampleGroupContext(description.format(subject), current, tags, {
val constructor =
subject.constructors.firstOrNull { it.parameters.isEmpty() } ?: throw IllegalArgumentException()
subject.constructors.firstOrNull { it.parameters.isEmpty() } ?: throw InstantiationException()
constructor.call()
}
})
current = context
SubjectKSpec<T>(this, context).apply(block)
current = current.parent ?: current
Expand Down
4 changes: 2 additions & 2 deletions kspec-core/src/main/kotlin/io/polymorphicpanda/kspec/Spec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import io.polymorphicpanda.kspec.tag.Tag
import kotlin.reflect.KClass

interface Spec {
fun group(description: String, block: () -> Unit)
fun <T: Any> group(subject: KClass<T>, description: String = "", block: SubjectSpec<T>.() -> Unit)
fun group(description: String, tags: Set<Tag>, block: () -> Unit)
fun <T: Any> group(subject: KClass<T>, description: String = "", tags: Set<Tag>, block: SubjectSpec<T>.() -> Unit)
fun example(description: String, tags: Set<Tag>, block: () -> Unit)
fun before(action: () -> Unit)
fun after(action: () -> Unit)
Expand Down
54 changes: 46 additions & 8 deletions kspec-core/src/main/kotlin/io/polymorphicpanda/kspec/Terms.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,58 @@ import io.polymorphicpanda.kspec.tag.focus
import io.polymorphicpanda.kspec.tag.pending
import kotlin.reflect.KClass

fun Spec.describe(description: String, action: () -> Unit) {
group("describe: $description", action)
fun Spec.describe(description: String, vararg tags: Tag, action: () -> Unit) {
group("describe: $description", setOf(*tags),action)
}

fun <T: Any> Spec.describe(subject: KClass<T>, description: String = "%s", action: SubjectSpec<T>.() -> Unit) {
group(subject, "describe: $description", action)
fun <T: Any> Spec.describe(subject: KClass<T>, description: String = "%s",
vararg tags: Tag, action: SubjectSpec<T>.() -> Unit) {
group(subject, "describe: $description", setOf(*tags), action)
}

fun Spec.context(description: String, action: () -> Unit) {
group("context: $description", action)
fun Spec.context(description: String, vararg tags: Tag, action: () -> Unit) {
group("context: $description", setOf(*tags), action)
}

fun <T: Any> Spec.context(subject: KClass<T>, description: String = "%s", action: SubjectSpec<T>.() -> Unit) {
group(subject, "context: $description", action)
fun <T: Any> Spec.context(subject: KClass<T>, description: String = "%s",
vararg tags: Tag, action: SubjectSpec<T>.() -> Unit) {
group(subject, "context: $description", setOf(*tags), action)
}

fun Spec.fdescribe(description: String, vararg tags: Tag, action: () -> Unit) {
group("describe: $description", setOf(focus(), *tags),action)
}

fun <T: Any> Spec.fdescribe(subject: KClass<T>, description: String = "%s",
vararg tags: Tag, action: SubjectSpec<T>.() -> Unit) {
group(subject, "describe: $description", setOf(focus(), *tags), action)
}

fun Spec.fcontext(description: String, vararg tags: Tag, action: () -> Unit) {
group("context: $description", setOf(focus(), *tags), action)
}

fun <T: Any> Spec.fcontext(subject: KClass<T>, description: String = "%s",
vararg tags: Tag, action: SubjectSpec<T>.() -> Unit) {
group(subject, "context: $description", setOf(focus(), *tags), action)
}

fun Spec.xdescribe(description: String, reason: String? = null, action: () -> Unit) {
group("describe: $description", setOf(pending(reason ?: "No reason provided")),action)
}

fun <T: Any> Spec.xdescribe(subject: KClass<T>, description: String = "%s",
reason: String? = null, action: SubjectSpec<T>.() -> Unit) {
group(subject, "describe: $description", setOf(pending(reason ?: "No reason provided")), action)
}

fun Spec.xcontext(description: String, reason: String? = null, action: () -> Unit) {
group("context: $description", setOf(pending(reason ?: "No reason provided")), action)
}

fun <T: Any> Spec.xcontext(subject: KClass<T>, description: String = "%s",
reason: String? = null, action: SubjectSpec<T>.() -> Unit) {
group(subject, "context: $description", setOf(pending(reason ?: "No reason provided")), action)
}

fun Spec.it(description: String, vararg tags: Tag, action: () -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.polymorphicpanda.kspec.config

import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.Context
import io.polymorphicpanda.kspec.hook.AroundHook
import io.polymorphicpanda.kspec.hook.Chain
import io.polymorphicpanda.kspec.hook.SimpleHook
Expand All @@ -22,15 +22,15 @@ class KSpecConfig {

val filter = FilterConfig()

fun before(vararg tags: Tag, block: (ExampleContext) -> Unit) {
fun before(vararg tags: Tag, block: (Context) -> Unit) {
_before.add(SimpleHook(block, setOf(*tags)))
}

fun after(vararg tags: Tag, block: (ExampleContext) -> Unit) {
fun after(vararg tags: Tag, block: (Context) -> Unit) {
_after.add(SimpleHook(block, setOf(*tags)))
}

fun around(vararg tags: Tag, block: (ExampleContext, Chain) -> Unit) {
fun around(vararg tags: Tag, block: (Context, Chain) -> Unit) {
_around.add(AroundHook(block, setOf(*tags)))
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package io.polymorphicpanda.kspec.context

import io.polymorphicpanda.kspec.tag.Tag
import io.polymorphicpanda.kspec.tag.Taggable
import java.util.*

open class Context(val description: String)
open class Context(val description: String, parent: Taggable?, tags: Set<Tag>): Taggable(parent, tags)

class ExampleGroupContext(description: String,
val parent: ExampleGroupContext?,
tags: Set<Tag> = setOf<Tag>(),
var subjectFactory: () -> Any? = { throw UnsupportedOperationException() })
: Context(description) {
: Context(description, parent, tags) {
internal val children = LinkedList<Context>()

private var subjectInstance: Any? = null
Expand Down Expand Up @@ -41,7 +43,6 @@ class ExampleGroupContext(description: String,
subjectInstance = null
}


companion object {
private fun doVisit(visitor: ContextVisitor, context: Context): ContextVisitResult {
when(context) {
Expand Down Expand Up @@ -70,9 +71,7 @@ class ExampleGroupContext(description: String,

class ExampleContext(description: String, val parent: ExampleGroupContext,
val action: (() -> Unit)?, tags: Set<Tag> = setOf<Tag>())
: Context(description) {

val tags = HashSet<Tag>(tags)
: Context(description, parent, tags) {

init {
parent.children.add(this)
Expand All @@ -82,10 +81,4 @@ class ExampleContext(description: String, val parent: ExampleGroupContext,
parent.reset()
action!!()
}

fun contains(vararg tags: Tag): Boolean = this.tags.any { tags.contains(it) }

fun contains(tags: Collection<Tag>): Boolean = this.tags.any { tags.contains(it) }

operator fun get(tag: String): Tag? = tags.firstOrNull { it.name == tag }
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package io.polymorphicpanda.kspec.filter

import io.polymorphicpanda.kspec.config.KSpecConfig
import io.polymorphicpanda.kspec.context.ContextVisitResult
import io.polymorphicpanda.kspec.context.ContextVisitor
import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.ExampleGroupContext
import io.polymorphicpanda.kspec.context.*
import io.polymorphicpanda.kspec.extension.Extension
import io.polymorphicpanda.kspec.tag.Ignored
import io.polymorphicpanda.kspec.tag.Tag
Expand All @@ -19,9 +16,9 @@ object Filter: Extension {
val match = config.filter.match

if (match.isNotEmpty() && hasMatch(match, root)) {
config.around { example, chain ->
if (example.contains(match)) {
chain.next(example)
config.around { context, chain ->
if (context.contains(match) || (context is ExampleGroupContext && hasMatch(match, context))) {
chain.next(context)
} else {
chain.stop("Not matching include filter")
}
Expand All @@ -31,9 +28,9 @@ object Filter: Extension {
val includes = config.filter.includes

if (includes.isNotEmpty()) {
config.around { example, chain ->
if (example.contains(includes)) {
chain.next(example)
config.around { context, chain ->
if (context.contains(includes) || (context is ExampleGroupContext && hasMatch(includes, context))) {
chain.next(context)
} else {
chain.stop("Not matching include filter")
}
Expand All @@ -43,11 +40,11 @@ object Filter: Extension {
val excludes = config.filter.excludes

if (excludes.isNotEmpty()) {
config.around { example, chain ->
if (!example.contains(excludes)) {
chain.next(example)
config.around { context, chain ->
if (!context.contains(excludes) || (context is ExampleGroupContext && hasMatch(excludes, context))) {
chain.next(context)
} else {
val ignored = example.tags.filterIsInstance(Ignored::class.java).firstOrNull()
val ignored = context.tags.filterIsInstance(Ignored::class.java).firstOrNull()
if (ignored != null) {
chain.stop(ignored.reason)
} else {
Expand All @@ -62,21 +59,20 @@ object Filter: Extension {
fun hasMatch(tags: Set<Tag>, root: ExampleGroupContext): Boolean {
val check = object: ContextVisitor {
var match = false
override fun preVisitExampleGroup(context: ExampleGroupContext): ContextVisitResult {
return ContextVisitResult.CONTINUE
}
override fun preVisitExampleGroup(context: ExampleGroupContext) = hasMatch(context)

override fun postVisitExampleGroup(context: ExampleGroupContext) = ContextVisitResult.CONTINUE

override fun onVisitExample(context: ExampleContext): ContextVisitResult {
override fun onVisitExample(context: ExampleContext) = hasMatch(context)

private fun hasMatch(context: Context): ContextVisitResult {
match = tags.any {
context.contains(it)
}

if (match) {
return ContextVisitResult.TERMINATE
}

return ContextVisitResult.CONTINUE
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.polymorphicpanda.kspec.hook

import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.Context
import io.polymorphicpanda.kspec.tag.Tag

/**
* @author Ranie Jade Ramiso
*/
class AroundHook(val block: (ExampleContext, Chain) -> Unit, tags: Set<Tag>): Hook(tags) {
fun execute(example: ExampleContext, chain: Chain) {
block(example, chain)
class AroundHook(val block: (Context, Chain) -> Unit, tags: Set<Tag>): Hook(tags) {
fun execute(context: Context, chain: Chain) {
block(context, chain)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.polymorphicpanda.kspec.hook

import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.Context

/**
* @author Ranie Jade Ramiso
*/
abstract class Chain(val list: List<AroundHook>) {
var iterator = list.iterator()

fun next(example: ExampleContext) {
iterator.next().execute(example, this)
fun next(context: Context) {
iterator.next().execute(context, this)
}

abstract fun stop(reason: String)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.polymorphicpanda.kspec.hook

import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.Context
import io.polymorphicpanda.kspec.tag.Tag

/**
* @author Ranie Jade Ramiso
*/
abstract class Hook(val tags: Set<Tag>) {
fun handles(example: ExampleContext): Boolean {
return example.tags.containsAll(tags)
fun handles(context: Context): Boolean {
return context.tags.containsAll(tags)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package io.polymorphicpanda.kspec.hook

import io.polymorphicpanda.kspec.context.ExampleContext
import io.polymorphicpanda.kspec.context.Context
import io.polymorphicpanda.kspec.tag.Tag

/**
* @author Ranie Jade Ramiso
*/
class SimpleHook(val block: (ExampleContext) -> Unit, tags: Set<Tag>): Hook(tags) {
fun execute(example: ExampleContext) {
block(example)
class SimpleHook(val block: (Context) -> Unit, tags: Set<Tag>): Hook(tags) {
fun execute(context: Context) {
block(context)
}
}

0 comments on commit 8c6a66e

Please sign in to comment.