All Versions
21
Latest Version
Avg Release Cycle
47 days
Latest Release
220 days ago

Changelog History
Page 2

  • v0.9.0-alpha2 Changes

    January 11, 2020

    This is a pre-release for early adopters using currently cc.en_GB and want to switch to fluent.en_GB which makes use of Expect instead of Assert

    Following the setup instructions:

    dependencies {
        testImplementation "ch.tutteli.atrium:atrium-fluent-en_GB:0.9.0-alpha2"
    }
    

    ๐Ÿš€ Proper release notes will follow with the final release of 0.9.0.
    Already many thanks to all the contributors

    Following already the migration guide.

    ๐Ÿ—„ Migrating deprecated functionality

    ๐Ÿš€ In case you migrate from a version < 0.7.0 then please have a look at the migration guide given in the Release Notes of 0.7.0.
    Otherwise you can use the suggested replacements (ALT + Enter -> Replace with ...) or the search/replace patterns shown below.

    Notice, that you don't have to migrate everything at once where asExpect and asAssert allow to switch between the old Assert and the new Expect world.
    Ping us in the Atrium slack channel if you need help.

    The following command is carrying out the points 1 to 10 described below (don't forget the points 11, 12, ...), run it from the root of your project, no guarantees that your system is capable of carrying it out. If not, you can use the manual steps described below.

    find ./ -name "*.kt" | xargs perl -0777 -i \
    -pe 's/AssertImpl([\n\r\s]*)\.changeSubject\(([^\)\n]+)\)[\n\r\s]*\{[\n\r\s]*subject/ExpectImpl$1.changeSubject\($2\)$1.unreported \{ it/g;' \
    -pe 's/AssertImpl([\n\r\s]*)\.changeSubject\(([^\)]+)\)/ExpectImpl$1.changeSubject\($2\).unreported/g;' \
    -pe 's/AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.createDescriptive\(([^,\n]+,[^\)]+\)[\n\r\s]*\{[\n\r\s]*)plant.subject/AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.createDescriptive\(([^,\n]+,[^\)]+\)[\n\r\s]*\{[\n\r\s]*)plant.subject/g;' \
    -pe 's/AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.descriptive([\n\r\s]*).withTest(\(?[\n\r\s]*)\{([\n\r\s]*)plant.subject/AssertImpl$1.builder$2.descriptive$3.withTest\(plant\)$4\{$5it/g;' \
    -pe 's/AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.descriptive([\n\r\s]*).withTest(\(?[\n\r\s]*)\{([\n\r\s]*)subject/AssertImpl$1.builder$2.descriptive$3.withTest\(this\)$4\{$5it/g;' \
    -pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)/feature(\{ f(it::$1) \})$2/g;' \
    -pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)/feature \{ f(it::$1) \}/g;' \
    -pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)`/feature(\{ f(it::$1) \})$2/g;' \
    -pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)/feature($1::$2)/g;' \
    -pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)/feature("$1.$2", { $1.$2 })/g;' \
    -pe 's/(import ch\.tutteli\.atrium\.api\.cc\.(?:\.infix)?(?:en_GB|de_CH))\.(property|returnValueOf)/$1.feature/g;' \
    -pe 's/(\.| )((?:toThrow|wirft|isA|istEin)<.*>)\s*\{\s*\}/$1$2()/g;' \
    -pe 's/notToBeNull\s*\{\s*\}/notToBe(null)/g;' \
    -pe 's/fun <T\s*:\s*Any> ([^\(]+)\(subject:\s*T\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlant\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[\n\r\s]*reporter\)/fun <T> $1\(subject: T\): Expect<T> = \n ExpectBuilder.forSubject\(subject\)\n .withVerb\($2\)\n .withoutOptions\(\)\n .build\(\)/g;' \
    -pe 's/fun <T\s*:\s*Any> ([^\(]+)\(subject:\s*T\s*,[\n\r\s]*assertionCreator: Assert<T>.\(\)\s*->\s*Unit\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlantAndAddAssertionsCreatedBy\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[\n\r\s]*reporter,[\n\r\s]*assertionCreator\)/fun <T> $1\(subject: T, assertionCreator: Expect<T>.\(\) -> Unit\): Expect<T> = \n $1(subject).addAssertionsCreatedBy(assertionCreator)/g;' \
    -pe 's/(?:internal )?fun <T(?:\s*:\s*Any\?)?> ([^\(]+)\(subject:\s*T\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlantNullable\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[^\)]+\)//g;' \
    -pe 's/import ch.tutteli.atrium.verbs\.(expect|assert|assertThat)/import ch.tutteli.atrium.api.verbs.$1/g;' \
    -pe 's/AssertImpl/ExpectImpl/g;' \
    -pe 's/fun Assert(?:ionPlant(?:Nullable)?)?<(.*)>\./fun <T: $1> Expect<T>\./g;' \
    -pe 's/Assert(ionPlant(Nullable)?)?</Expect</g;' \
    -pe 's/import ch\.tutteli\.atrium\.creating\.Assert(ionPlant(Nullable)?)?/import ch.tutteli.atrium.creating.Expect/g;' \
    -pe 's/import ch.tutteli\.atrium\.api\.cc\.(en_GB|de_CH)/import ch.tutteli.atrium.api.fluent.$1/g;' \
    -pe 's/import ch.tutteli\.atrium\.api\.cc\.infix\.en_GB/import ch.tutteli.atrium.api.infix.en_GB/g;'
    

    The following list helps you to migrate faster by using a few regex search replace commands (in Intellij). Make sure you have checked Regex as well as Match Case in the search options. Notice, that the good will certainly not compile after a single replace, you need to carry out all search&replace commands.
    It is not perfect, maybe you need to do a few adjustments in addition, let us now and we improve the search/replace commands here.

    Switch to ExpectImpl.changeSubject instead of using AssertImpl.changeSubject:
    Search: AssertImpl([\n\r\s]*)\.changeSubject\(([^\)\n]+)\)[\n\r\s]*\{[\n\r\s]*subject
    Replace: ExpectImpl$1.changeSubject\($2\)$1.unreported { it

    Search: AssertImpl([\n\r\s]*)\.changeSubject\(([^\)]+)\)
    Replace: ExpectImpl$1.changeSubject\($2\).unreported

    ๐Ÿ— builder.descriptive, safe withTest

    ๐Ÿ— Search: AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.createDescriptive\(([^,\n]+,[^\)]+\)[\n\r\s]*\{[\n\r\s]*)plant.subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.createDescriptive\(plant, $3it

    ๐Ÿ— Search: AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.descriptive([\n\r\s]*).withTest(\(?[\n\r\s]*)\{([\n\r\s]*)plant.subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.descriptive$3.withTest\(plant\)$4{$5it

    ๐Ÿ— Search: AssertImpl([\n\r\s]*)\.builder([\n\r\s]*)\.descriptive([\n\r\s]*).withTest(\(?[\n\r\s]*)\{([\n\r\s]*)subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.descriptive$3.withTest\(this\)$4{$5it

    ๐Ÿ‘‰ use new feature mechanism

    This one needs extra care as arguments could be function calls. Verify the replacements

    Search: (?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)
    Replace: feature(\{ f(it::$1) \})$2

    Search: (?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)
    Replace: feature \{ f(it::$1) \}

    Search: (?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)
    Replace: feature($1::$2)

    Search: (?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)
    Replace: feature("$1.$2", { $1.$2 })

    Search: (import ch\.tutteli\.atrium\.api\.cc\.(?:\.infix)?(?:en_GB|de_CH))\.(property|returnValueOf)
    Replace: $1.feature

    toThrow and isA with empty assertionCreator lambda
    Search: (\.| )((?:toThrow|wirft|isA|istEin)<.*>)\s*\{\s*\}
    Replace $1$2()

    notToBeNull with empty assertionCreator lambda
    Search: notToBeNull\s*\{\s*\}
    Replace: notToBe(null)

    migrate custom assertion verbs:

    Search: fun <T\s*:\s*Any> ([^\(]+)\(subject:\s*T\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlant\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[\n\r\s]*reporter\)
    Replace:
    ๐Ÿ— fun <T> $1\(subject: T\): Expect<T> = \n ExpectBuilder.forSubject\(subject\)\n .withVerb\($2\)\n .withoutOptions\(\)\n .build\(\)

    Search:
    fun <T\s*:\s*Any> ([^\(]+)\(subject:\s*T\s*,[\n\r\s]*assertionCreator: Assert<T>.\(\)\s*->\s*Unit\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlantAndAddAssertionsCreatedBy\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[\n\r\s]*reporter,[\n\r\s]*assertionCreator\)
    Replace:
    fun <T> $1\(subject: T, assertionCreator: Expect<T>.\(\) -> Unit\): Expect<T> = \n $1(subject).addAssertionsCreatedBy(assertionCreator)

    Search:
    (?:internal )?fun <T(?:\s*:\s*Any\?)?> ([^\(]+)\(subject:\s*T\)[\n\r\s]*=[\n\r\s]*AssertImpl[\n\r\s]*\.coreFactory[\n\r\s]*\.newReportingPlantNullable\(([^,]+),[\n\r\s]*\{\s*subject\s*\}[\n\r\s]*,[^\)]+\)
    Replace: (empty string)

    In case the above search&replace did not find anything (because your code is different):
    โ™ป๏ธ Switch from AssertImpl.coreFactory.newReportingPlant to ExpectBuilder
    ๐Ÿ— => see atriumVerbs.kt for an example of how own assertion verbs are defined now; or use the suggested replacements but please add import ch.tutteli.atrium.domain.builders.reporting.ExpectBuilder first as it will not work correctly otherwise due to an Intellij bug
    => Note that you don't need a verb for nullable types any more. Thus:

    • remove the upper bound T: Any
    • remove the verb which uses `newReportingPlantNullable
    • remove the verb which expected act: () -> Unit

    Switch to new built-in assertion verbs which use Expect

    Search: import ch.tutteli.atrium.verbs.(expect|assert|assertThat)
    Replace: import ch.tutteli.atrium.api.verbs.$1

    Switch from AssertImpl to ExpectImpl

    Search: AssertImpl
    Replace: ExpectImpl

    Switch all your assertion functions to use Expect and no longer Assert:

    Search: import ch\.tutteli\.atrium\.creating\.Assert(ionPlant(Nullable)?)?
    Replace: import ch.tutteli.atrium.creating.Expect

    Search: fun Assert(?:ionPlant(?:Nullable)?)?<(.*)>\.
    Replace: fun <T: $1> Expect<T>\.

    Search: Assert(ionPlant(Nullable)?)?<
    Replace: Expect<

    Switch the API

    Search: import ch.tutteli\.atrium\.api\.cc\.(en_GB|de_CH)
    Replace: import ch.tutteli.atrium.api.fluent.$1

    Search: import ch.tutteli\.atrium\.api\.cc\.infix\.en_GB
    Replace: import ch.tutteli.atrium.api.infix.en_GB

    In case you have custom assertion verbs
    Dealing with thrown exceptions is now handled by Expect as well.
    ๐Ÿ‘ป However, in case you have named the assertion verb differently for expecting an Exception then you have to decide:

    • ๐Ÿšš use the same name => rename the corresponding function which expects act: () -> Unit to the same name and remove it afterwards
    • ๐Ÿ‘‰ use a different name => delegate the function which expects act: () -> Unit to the other verb

    ๐Ÿ— Check if you need to add import ch.tutteli.atrium.domain.builders.reporting.ExpectBuilder

    Try to reduce duplicate Expect imports
    Repeat until you don't have duplicate imports anymore
    Search: import ch\.tutteli\.atrium\.creating\.Expect\n\s*import ch\.tutteli\.atrium\.creating\.Expect
    Replace: import ch.tutteli.atrium.creating.Expect

    โš  Try to compile your project and watch out for the following warnings:

    • 'MyClass' is a final type, and thus a value of the type parameter is predetermined
      => you can suppress this warning by adding @file:Suppress("FINAL_UPPER_BOUND") to your file, this is actually a Kotlin bug (https://youtrack.jetbrains.com/issue/KT-34257)
  • v0.9.0-alpha Changes

    August 29, 2019

    This is a pre-release for early adopters using currently cc.en_GB and want to switch to fluent.en_GB which makes use of Expect instead of Assert

    Following the setup instructions:

    dependencies {
        testImplementation "ch.tutteli.atrium:atrium-fluent-en_GB:0.9.0-alpha"
    }
    

    ๐Ÿš€ Proper release notes will follow with the final release of 0.9.0, following already the migration guide

    ๐Ÿ—„ Migrating deprecated functionality

    ๐Ÿš€ In case you migrate from a version < 0.7.0 then please have a look at the migration guide given in the Release Notes of 0.7.0.
    Otherwise you can use the suggested replacements (ALT + Enter -> Replace with ...) or the search/replace patterns shown below.

    ๐Ÿ”” Notice, that you don't have to migrate everything at once where asExpect and asAssert allow to switch between the old Assert and the new Expect world.
    Ping us in the Atrium slack channel if you need help.

    Following a few hints how you can migrate faster by using a few regex search replace commands (make sure you have checked Regex in the search) -- it might be the search replace is not enough for your use case and require a few adjustements from your part) :

    Switch all your assertion functions to use Expect and no longer Assert:

    Search: import ch.tutteli.atrium.creating.Assert(ionPlant(Nullable)?)?
    Replace: import ch.tutteli.atrium.creating.Expect

    Repeat until you don't have duplicate imports anymore
    Search: import ch.tutteli.atrium.creating.Expect\n\s*ch.tutteli.atrium.creating.Expect
    Replace: import ch.tutteli.atrium.creating.Expect

    Search: Assert(ionPlant(Nullable)?)?<
    Replace: Expect<

    Switch to ExpectImpl.changeSubject instead of using AssertImpl.changeSubject:
    Search: AssertImpl([\n\r\s]).changeSubject(([)\n]+))[\n\r\s]{[\n\r\s]*subject
    Replace: ExpectImpl$1.changeSubject$1.unreported($2) { it

    Search: AssertImpl([\n\r\s]*).changeSubject(([)]+))
    Replace: ExpectImpl$1changeSubject.unreported($1)

    ๐Ÿ— builder.descriptive, safe withTest

    ๐Ÿ— Search: AssertImpl([\n\r\s]).builder([\n\r\s]).createDescriptive(([,\n]+,[)]+)[\n\r\s]{[\n\r\s])plant.subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.createDescriptive(plant, $3it

    ๐Ÿ— Search: AssertImpl([\n\r\s]).builder([\n\r\s]).descriptive([\n\r\s]).withTest((?[\n\r\s]){([\n\r\s]*)plant.subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.descriptive$3.withTest(plant)$4{$5it

    ๐Ÿ— Search: AssertImpl([\n\r\s]).builder([\n\r\s]).descriptive([\n\r\s]).withTest((?[\n\r\s]){([\n\r\s]*)subject
    ๐Ÿ— Replace: AssertImpl$1.builder$2.descriptive$3.withTest(this)$4{$5it

    ๐Ÿ‘‰ use new feature mechanism

    This one needs extra care as arguments could be function calls. Verify the replacements

    Search: (?:property|returnValueOf|rueckgabewertVon)(subject::([)]+)).
    Replace: feature { f(it::$1) }.

    Search: (?:property|returnValueOf|rueckgabewertVon)(subject::([)]+))(\s*{)
    Replace: feature({ f(it::$1) })$2$

    Search: (?:property|returnValueOf|rueckgabewertVon)(([:]+)::([)]+))
    Replace: feature($1::$2)

    toThrow with empty assertionCreator lambda
    Search: .((?:toThrow|wirft|isA|istEin)<[>]+>)\s*{\s*}
    Replace .$1()

    migrate custom assertion verbs
    โ™ป๏ธ Switch from AssertImpl.coreFactory.newReportingPlant to ExpectImpl.assertionVerbBuilder
    ๐Ÿ‘€ see atriumVerbs.kt for an example

  • v0.8.0 Changes

    April 28, 2019

    Jar's can be found here: https://bintray.com/robstoll/tutteli-jars/atrium/0.8.0
    API Maturity : Stable
    Implementation Maturity : Almost Stable

    ๐Ÿš€ There won't be any breaking changes in the API (assertion functions/builders) until v1.0.0 besides parameter name renaming. But we want to progress as well and deprecate functionality in each version (e.g quite a lot with 0.7.0; please replace deprecated functionality until v1.0.0 where we will remove it.
    โœ… However, we do not provide yet a stable API for the domain and core modules of Atrium -- it is almost stable, but there might be slight breaking changes which we want to introduce before v1.0.0. That is also the reason why we do not have yet established backward compatibility tests for domain/core. This might affect you if you write your own assertion functions. And it also affects you if you provide your own implementation for parts of Atrium.

    Table of Content

    • ๐Ÿ†• New Features
      • API
      • Domain/Core aka write own assertion functions
      • Others
    • ๐Ÿ›  Fixes
    • Improvments
    • ๐Ÿ’ฅ Breaking Changes
    • ๐Ÿ—„ Deprecation
    • ๐Ÿ—„ Migrating deprecated functionality

    ๐Ÿ†• New Features

    API

    • #27 containsExactly as replacement for containsStrictly, thanks to @msmoljan for the implementation and thanks to @christophsturm for the idea
    • #33 isNotBlank for CharSequence, thanks to @pt2121 for the implementation
    • #39 make atLeast optional for CharSequence.contains, thanks to @christophsturm for the idea
    • #51 keys and values for Map to postulate assertions about the keys or values of a Map
    • #37 asEntries for Map, thanks to @arjank for the implementation
    • #29/#75 getExisting for Map to postulate assertions about the value of a corresponding key
    • #28 containskey, #59 containsNotKey for Map, thanks to @uaArsen for the implementation
    • #61/#62 contains for Map
    • #30/#76 get for List
    • #53 notToThrow as counterpart of toThrow - thanks to @charleskorn for the idea
    • #65 shortcut property/fun for Pair.first and Pair.second
    • #25 isKeyValue as well as shortcut property/fun key/value for Map.Entry
    • #69 toBe was opened up for nullable subjects (accepts now Any?), thanks to @dave08 for the discussion
    • #70 toBeNullIfNullElse for nullable subjects, thanks to @dave08 for the idea
    • #71 shortcut property/fun Collection.size
    • #78 containsExactly with single assertion creator
    • #48 asIterable with assertionCreator block
    • #46 o as alternative to this in sub-assertions for the infix API

    Domain / Core

    ๐Ÿ”‹ Features for assertion-function-writers:

    • #67 AssertImpl.mapArguments -> to map a variable length argument lists of the form first: T, vararg rest: T (inside a function T, Array<out T>) to R, Array<out R>
    • #72 changeSubject to a nullable type
    • AssertImpl.feature.extractor -> in case you want to make an assertion about a feature which is not always safe to extract (e.g. List.get expects a suitable index)
    • โœจ AssertImpl.collector.collectOrExplain => collects assertions for later usage but only if it is safe to collect them, otherwise it wraps them into an explanatory assertion so that it can be used to enhance reporting
    • AssertImpl.collector.collectNullable which allows to collect assertions for a nullable subject (for AssertionPlantNullable instead of AssertionPlant)

    Others

    • turned Atrium into an multi-platform project; all dependencies are also available for:
      • the JS platform => use the -js suffix; you will have to migrate to bundle en_GB if you still use en_UK, see Migrating deprecated functionality below.
      • the Android platform => use the -android suffix => Thansk to @ultraon for reporting #52 regarding issues with module-info.class
    • ๐Ÿ—„ #41 deprecated notToBeNullBut for BigDecimal
    • ๐Ÿ—„ #55 infix API - deprecated calls to toBe if a keyword is passed inadvertently
    • โœ… stacktraces in error reporting should no longer contain stack frames of Atrium or test runners

    ๐Ÿ›  Fixes

    • none this time

    ๐Ÿ‘Œ Improvements

    • DetailedObjectFormatter shows now Kotlin types instead of Java types (e.g. kotlin.Int instead of java.lang.Integer).
    • an AtriumError is now thrown instead of an AssertionError (AtriumError is a subtype of AssertionError)

    ๐Ÿ’ฅ Breaking Changes

    Planned (previously deprecated or announced)

    • none this time

    Unplaned

    • Made Group, GroupWithoutNullableEntries and GroupWithNullableEntries invariant. I doubt this will be a problem for someone, otherwise let me know
    • Made Value, Values, Entry, Entries invariant; in case you get problems, try to use user-site variance and specify out there
      The following breaking changes only bother you if you implemented an own core. Most have been necessary to turn Atrium into a multi-platform project:
    • core uses now an own implementation of Locale and no longer java.util.Locale
    • core uses now KClass instead of Class
    • TranslatableWithArgs takes a List instead of an Array as parameter
    • Reporter needs to provide an AtriumErrorAdjuster in addition
    • โœ‚ removed duplicate anyAssertions in package ch.tutteli.atrium.domain.creating.any.typetransformation.creators (use the one from package ch.tutteli.atrium.domain.creating)

    tl;dr the following is only of interest if you rely on binary compatibility
    I changed the JvmName of contains? in cc-en_UK and cc-infix-en_UK to containsDeprecated and enthaelt? in cc-de_CH to enthaeltDeprecated due to the DEX compiler for android which cannot handle ? in identifiers. This is a binary backward compatibility break for a method which I introduced in 0.7.0 to retain source backward compatibility. In case you use still use cc-en_UK or cc-infix-en_UK and rely on binary compatibility you will have to recompile when updating to 0.8.0.

    ๐Ÿ—„ Deprecation

    ๐Ÿšš The following was deprecated and will be removed with 1.0.0:

    • Assert<Iterable>.containsStrictly use containsExactly instead.
    • ๐ŸŒ ReporterBuilder::withoutTranslations using java.util.Locale => use Atrium's Locale
    • 0๏ธโƒฃ TranslatorOption::withDefaultTranslator using java.util.Locale => use Atrium's Locale
    • 0๏ธโƒฃ TextAssertionFormatterOption::withDefaultTextCapabilities => use withTextCapabilities which uses KClass instead of Class
    • ๐Ÿ”ง AtriumErrorAdjusterOption::withOnlyFailureReporter and withCustomReporter => new step in configuration, use either withDefaultAtriumErrorAdjusters or choose one of the other options
    • ๐Ÿ‘€ all functions containing nullable in their name => their counterpart without nullable in their name where opened up to accept also nullable types (see #60 for details)

    Possible Breaking Changes with 0.9.0

    • I will prepare the transition to Assert<T> instead of Assert<out T>. I will turn Assert into an own type (currently only a type alias) - you should not notice something but it means that the binary code will change when you compile against 0.9.0
    • โœ… I might reuse opentest4j exceptions to improve error reporting in IDEs. For this to work I might have to make modifications to Assertion/AssertionGroup (would only affect core implementors).
    • ๐Ÿ‘ป An exception will be thrown where one has to define an assertionCreator -- shall prevent kind of dead code/incomplete assertions; for instance assert(mapOf("a" to 1)).keys {}
      • same for addAssertionsCreatedBy/and {}; they will throw an exception if no sub-assertion is defined
    • toBe, contains etc. which expect T where <T: Any> might be restricted to input types, so that comparing apple with oranges is no longer possible without explicitly stating the type. E.g. assert(1).toBe("hello")would be a compile error

    Possible Breaking Changes with 1.0.0

    Please open an issue if you are not happy with one of the changes and state why or contact me via the Atrium slack channel.

    Assert<Throwable>.message{} will return Assert<Throwable> instead of Unit

    Assert<T>.isA{} will return Assert<T> instead of Unit

    All property and returnValueOf taking an assertionCreator will return the same type as the current subject.

    ๐Ÿšš I will remove out of Assert<out T> in order that things like asssert(1).toBe("hello") is no longer possible, overloads can be simplified etc.

    returnValueOf functions might be renamed to returnValueOfX where X denotes the number of arguments. Too often it occurs that Kotlin is not able to infer the correct overload, the user does not get the appropriate help in code completion or the error message is too big. This should help.

    ๐Ÿ”‹ feature assertion functions might require a lambda in the future. This way error reporting does not blow up in the middle of the way because subject is not available. However, there is a bug concerning nullable-features in Kotlin which prevents me from doing it at the moment: https://youtrack.jetbrains.com/issue/KT-23768, please up-vote it.

    A type parameter might be added to AssertionGroup to restrict the AssertionGroupType.

    ๐Ÿ“ฆ BulletPointIdentifier together with subtypes (AssertionGroupTypes) might be moved to another package: ch.tutteli.atrium.reporting.assertions

    ๐Ÿ‘€ AssertionPlant/Assert will switch roles => AssertionPlant will be the typealias of Assert, see #26; should only break binary compatibility

    ๐Ÿ‘€ I will introduce interface groups for RepoterBuilder as I did in other cases (e.g. see Descriptive); should only break binary compatibility

    ๐Ÿ—„ Migrating deprecated functionality

    ๐Ÿš€ In case you migrate from a version < 0.7.0 then please have a look at the migration guide given in the Release Notes of 0.7.0.
    Otherwise you can use the suggested replacements (ALT + Enter -> Replace with ...)

    Ping me in the Atrium slack channel if you need help.

  • v0.8.0-RC1

    April 13, 2019
  • v0.8.0-beta

    April 13, 2019
  • v0.8.0-alpha

    January 19, 2019
  • v0.7.0 Changes

    November 29, 2018

    ๐Ÿš€ See https://github.com/robstoll/atrium/releases/tag/v0.7.0 for full information. This is a patch-fix-version for Android because the DEX compiler cannot handle ? in identifiers and treats module-info.class as normal classes instead of ignoring it.

    ๐Ÿ‘ v0.8.0 of Atrium will support JS as additional platform and will most probably provide a specific artifact for Android as well. Simplified this means, we won't ship an atrium.jar with 0.8.0-android as version but atrium-android.jar with version 0.8.0.

  • v0.7.0-RC2

    January 19, 2019
  • v0.7.0-RC1

    January 19, 2019
  • v0.7.0-android Changes

    November 29, 2018

    ๐Ÿš€ See https://github.com/robstoll/atrium/releases/tag/v0.7.0 for full information. This is a patch-fix-version for Android because the DEX compiler cannot handle ? in identifiers and treats module-info.class as normal classes instead of ignoring it.

    ๐Ÿ‘ v0.8.0 of Atrium will support JS as additional platform and will most probably provide a specific artifact for Android as well. Simplified this means, we won't ship an atrium.jar with 0.8.0-android as version but atrium-android.jar with version 0.8.0.