Skip to content

Requirements

Joshua Gleitze edited this page Sep 2, 2019 · 14 revisions

This page shall show which requirements Atrium wants to fulfil, why and for whom.

Personas

We see roughly three Personas using Atrium:

  1. Newcomer, a developer which uses only built-in functionality provided by Atrium's API => new assertion functions are only created by composing other assertion functions. This user would come up with something like:

    fun <T: Date> Expect<T>.isBetween(lowerBoundInclusive: T, upperBoundExclusive: T) =
        isGreaterOrEquals(lowerBoundInclusive).and.isLessThan(upperBoundExclusive)
  2. Long-term User, a developer which uses Atrium but also invents new simple assertion functions. A user who uses Atrium already for a longer time. This user would come up with something like:

    fun Expect<Int>.isEven() = 
        createAndAddAssertion("is", RawString.create("an even number")) { it % 2 == 0 }
  3. Library author, a developer which uses Atrium but also invents more complex assertion functions for own types. Could be a library author or someone which actually wants to understand Atrium fully to get most out of it. This user would come up with something like:

    fun <A, B> Expect<Either<A, B>>.isLeft(): Expect<A> = changeToLeft().getExpectOfFeature()
    fun <A, B> Expect<Either<A, B>>.isLeft(assertionCreator: Expect<A>.() -> Unit) =
        changeToLeft().addToInitial(assertionCreator)
    
    private fun <A, B> Expect<Either<A, B>>.changeToLeft(): ChangedSubjectPostStep<Either<A, B>, A> {
        return ExpectImpl.changeSubject.reportBuilder(this)
            .withDescriptionAndRepresentation("is a", RawString.create("Left"))
            .withCheck { it.isLeft() }
            .withTransformation { (it as Left).a }
            .build()
    }

Requirements

R1: Separation of infix and fluent API

Must/shall: must
For whom: all
Reasons:

  • Mixing different styles lead to different code in the same codebase which we want to prevent in the first place (a user can depend on two APIs if desired).
  • the learning curve is higher as there are multiple ways of achieving the same
  • especially newcomers are left in uncertainty which version they should use (fluent or infix) and if there are differences between the two versions

R2: Global Implementation Replacement

Must/shall: must
For whom: all

Users should be able to replace certain parts of atrium’s implementation. In particular, the Reporter, Translation and Assertions implementation should be replaceable. When the implementation is replaced globally, there is no “dangling” entry point that would use the un-replaced functionality. For example: If the user replaces the implementation of Expect<Any>.toBe, there is no version of Expect<Any>.toBe that could be used to access the old implmentation.

Reasons:

  • there may be implementation decisions in that make sense for the project atrium but do not suit all users
  • having multiple implementations of the same “thing” available can lead to subtle bugs
Clone this wiki locally