atrium

A multiplatform expectation library for Kotlin

OTHER License

Stars
537
Committers
113

Bot releases are hidden (Show)

atrium - toHoldThirdPartyExpectation, extractSubject Latest Release

Published by robstoll 7 months ago

Table of Content

Full Changelog: https://github.com/robstoll/atrium/compare/v1.1.0...v1.2.0

New Features

All APIs

api-fluent

  • introduce CharSequence...matchFor(Regex) as replacement of regex(Regex) #1499 (matchFor already exists in api-infix, thus api-fluent only)

api-infx

  • no infix only additions this time

Logic / Core

  • withHelpOnFailureBasedOnDefinedSubject has now an showOnlyIf parameter which allows to define an optional predicate next to the check that the subject is present (otherwise the failure hint is not shown) #1674
  • use better names than TSub, TExpected, TNotExpected #1706 (thanks to @vlsi for the idea)

Fixes

  • Library lacks support for IR compiler #1481
  • workaround intellij KotlinJs bug which removes column numbers in stack traces #1655
  • only last failing expectation(-group) is shown in reporting #1705

Improvements

  • apply publishing plugins, esp. tutteli-dokka only if env PUB is true #1612
  • use IR-backend for JS
  • Improve/samples for Iterable.toContain.atLeast/butAtMost/atMost #1669 => thanks to @fergbaldo for some pre-work
  • add tests for reportOptions to MapToContainInOrderOnlyKeyValueExpectationsSpec #1129 => thanks to @simonNozaki for some pre-work
  • samples for Iterable feature extractors #1569 => => thanks to @constantine-zubrilin
  • Hyperlink for atrium-fluent in Examples section of README routes to non-existant file #1718 => thanks to @lkorsman

Deprecation

  • all enums in atrium-translations-de_CH were deprecated, switch to atrium-translations-en_GB (we will drop it with Atrium v1.3.0)

Deprecations with 1.3.0

We will make a major refactoring on core and logic level. Those changes should not affect most Atrium users. It might affect you if you:

  • created own expectation function based on assertionBuilder or other types which are defined in core or logic.
  • use an own expectation verb
  • we will drop the support for internationalization with 1.4.0, all functions involving Translatable will be deprecated in v1.3.0
  • might be we drop en_GB from package names
  • might be we move BulletPointProvider to another package

Migration steps/pointers will be provided in the release notes as usual.

The following changes are planned:

  • replace Assertion with Proof and along with it rename many types incorporating Assertion in its name or in its package's name => we will remove Assertion and co. with 1.5.0 at the latest)
  • re-write reporting entirely, a lot of types in ch.tutteli.atrium.reporting will be affected (could be we move this to 1.3.0)

Breaking Changes

Planned (previously deprecated or announced)

  • dropped support for Kotlin 1.3
  • we use the IR compiler backend for JS

Unplanned

  • we added an extra parameter (with default) to withHelpOnFailureBasedOnDefinedSubject, a binary BC, please re-compile

Breaking Changes with 1.3.0

  • we will drop support for translating the output - API might persist until 2.0.0 but we might already only use UsingDefaultTranslator
  • we might introduce interface groups for ReporterBuilder - binary compatibility break
  • BulletPointProvider might use a BulletPointIdentifier from a different package
  • we might drop the experimental expectExtension such as expect(...).withOptions provide it in a different form

Migrating deprecated functionality

Use the ReplaceWith in the corresponding @Deprecated annotations.

Please have a look at older release-notes in case you don't migrate from 1.0.0

Sponsors

We would like to thank   Tegonal Genossenschaft (Tegonal Cooperative, Bern, Switzerland) for sponsoring the time @robstoll is working on Atrium.

Are you using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - expectGrouped and drop Kotlin 1.2 support

Published by robstoll 12 months ago

Table of Content

Full Changelog: https://github.com/robstoll/atrium/compare/v1.0.0...v1.1.0

New Features

All APIs

  • introduce expectGrouped (ExpectGrouping) and group #1560 => see data-driven testing for examples and explanation
  • CharSequence.toContain....matchFor(Regex) as replacement for ...regex(Regex) #1499
  • Add notToBeAnInstanceOf #1400 => thanks to @AncutaIoan

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • no infix only additions this time

Logic / Core

  • none this time

Fixes

  • none this time

Improvements

  • change report for notToEqualNull #330 => thanks to @JordanllHarper
  • also discourage the usage of notToEqual in case of nullable BigDecimal #1507
  • typo fixed in README.md #1472 => thanks to @jufickel-b
  • restrict E in Expect<Optional>.toBePresent to : Any #1509 => thanks to @Nikos-Tsiougranas
  • add samples for BigDecimal expectation functions in api-infix #1505 => thanks to @VarunEnishetty
  • samples for CharSequence.toContain.atMost #1517 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain.atLeast.butAtMost #1515 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain.atMost #1517 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain.exactly #1516 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain...value #1520 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain...values #1519 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain...regex/matchFor #1521 => thanks to @Nikos-Tsiougranas
  • samples for CharSequence.toContain...elementsOf #1522 => thanks to @Nikos-Tsiougranas
  • samples for Iterable.toContain.exactly #1544 => thanks to @Nikos-Tsiougranas
  • samples for Map.toContain....entry #1555 => thanks to @danherrera
  • samples for Map.toContain....entries #1556 => thanks to @danherrera
  • samples for Map.toContain....entriesOf #1557 => thanks to @danherrera
  • add Map.toContain... infix samples #1567 => thanks to @danherrera
  • add CharSequence.ignoringCaseWithNotChecker sample #1571
  • add JVM kotest sample project #1325 => thanks to @ReccaFlames
  • use kotlin 1.8.21 but api/languageLevel 1.4 #1454 (except for the kotlin 1.3 module)
  • update to gradle 8.1.1 #1455
  • rewrite build to build-logic #1465 => big thanks to @vlsi for the idea and most of the work
  • introduce (build)libs.versions.toml and move yarn.lock into /gradle #1566
  • create sample project to demonstrate how Atrium can be used in combination with TestNG #1562 => thanks to @Zuretto

Deprecation

  • deprecated Kotlin 1.3 support, i.e. deprecated the package ch.tutteli.atrium.api.fluent.en_GB.kotlin_1_3 => we moved the functions to
    ch.tutteli.atrium.api.fluent.en_GB (same same for infix), use those instead
  • CharSequence.toContain....regex(Regex) => use ...matchFor(Regex)
  • api-infix: keyValues in the context of mapLike => use entries

Deprecations with 1.2.0

  • we will drop the support for internationalization with 1.3.0, all functions involving Translatable will be deprecated in v1.2.0

Deprecations with 1.3.0

We plan to make a major refactoring on core and logic level. Those changes should not affect most Atrium users. It might affect you if you:

  • created own expectation function based on assertionBuilder or other types which are defined in core or logic.
  • use an own expectation verb
  • might be we drop en_GB from package names
  • might be we move BulletPointProvider to another package

Migration steps/pointers will be provided in the release notes as usual.

The following changes are planned:

  • replace Assertion with Proof and along with it rename many types incorporating Assertion in its name or in its package's name => we will remove Assertion and co. with 1.5.0 at the latest)
  • re-write reporting entirely, a lot of types in ch.tutteli.atrium.reporting will be affected (could be we move this to 1.3.0)

Breaking Changes

Planned (previously deprecated or announced)

  • dropped support for Kotlin 1.2 (support for Kotlin 1.3 is deprecated and will be dropped with Atrium v1.2.0 -- we will emit languageLevel = 1.4, which in theory should still be consumable by Kotlin 1.3 as long as we don't use a feature which was introduced with Kotlin 1.4 -- no guarantee though)
  • we use the IR compiler backend for JVM
  • dropped the support for jdk 14 (i.e. we no longer build against it, most likely it still works without problems) and officially support jdk 17)

Unplanned

  • was planned to be deprecated but Windows was in the way due to its case-insensitive file system: we renamed the package ch.tutteli.atrium.api.fluent.en_GB.creating.charsequence.contains to charsequence.toCtonain` but dropped the old instead of deprecation -- same same for the infix API => this is a binary backward-compatibility break, please re-compile
  • renamed parameter name of Map... the keyValues from keyValues to entries since keyValues is deprecated in favour of entries. We don't expect that people are using named parameters with the infix API (as they disallow to use a function as infix call). But in cas you do, then please give feedback.
  • fixed typo in mapLikeToCntain => mapLikeToContain, this is a bc break, please re-compile

Breaking Changes with 1.2.0

  • we will switch from LEGACY compiler backend to IR backend for JS
  • we will drop support for translating the output - API will persist until 1.3.0 but we might already only use UsingDefaultTranslator
  • we might introduce interface groups for ReporterBuilder - binary compatibility break
  • we drop the kotlin_1_3 extension which was deprecated with Atrium 1.1.0
  • BulletPointProvider might use a BulletPointIdentifier from a different package
  • we might drop the experimental expectExtension such as expect(...).withOptions provide it in a different form

Migrating deprecated functionality

Use the ReplaceWith in the corresponding @Deprecated annotations.

Please have a look at older release-notes in case you don't migrate from 1.0.0

Sponsors

We would like to thank   Tegonal Genossenschaft (Tegonal Cooperative, Bern, Switzerland) for sponsoring the time @robstoll is working on Atrium.

Are you using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - 1.1.0 preview (not complete) and with JS IR support

Published by robstoll over 1 year ago

This is an extra release so that Atrium can be used with JS using the IR compiler backend.

Note that's not the final 1.1.0 version and that:

  • it lacks the kotlin_1_3 extension but the corresponding expectation functions are already integrated into the normal module. Iin case you also switch from LEGACY to IR and were using the kotlin_1_3 extension, then search and replace the import statement. search import ch.tutteli.atrium.api.fluent.en_GB.kotlin_1_3 and replace with import ch.tutteli.atrium.api.fluent.en_GB
  • it does not fix the backward-compatibility issues Jetbrains has introduces from LEGACY to IR -- in case you should see <unknown> (js: ...) in reporting, then it's due to the breaking change => I assume Atrium should still be usable in 99.99% of the cases
atrium - notToHaveElementsOr... and based on current Multiplatform Plugin

Published by robstoll over 1 year ago

Table of Content

Full Changelog: https://github.com/robstoll/atrium/compare/v0.18.0...v1.0.0

New Features

All APIs

  • notToHaveElementsOrAny
  • notToHaveElementsOrAll
  • notToHaveElementsOrNone
  • deprecate ChronoZonedDateTime.toBeLessThan etc. in favour of isBefore etc. #709 => thanks to @JordanllHarper
  • add asLocalDate for java.util.Date #1285 => thanks to @sajalverma17
  • add asLocalDateTime for java.util.Date #1286 => thanks to @Jujusp
  • undeprecate nested expect in preparation of #1330

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • no infix only additions this time

Logic / Core

  • none this time

Fixes

  • stackBacktrace is removed in JS when the NoOpAtriumErrorAdjuster is used #1383
  • Kotlin (1.4, 1.5) bug: Result unwrapping affects Atrium #1234 => thanks to @JordanllHarper

Improvements

  • Hint for not to contain #1156
  • Add icon for JetBrains IDEA / Toolbox #1434 => thanks @vlsi for the idea
  • Add a version switcher to the Code Documentation: https://docs.atriumlib.org and and out-of-date warning

build

  • Redo Build Logic #744 (update MPP plugins from old to new plugins)
  • rewrite readme-examples/build.gradle to build.gradle.kts #1159 => thanks to @jakubriegel
  • rewrite misc/tools/atrium-js-sample-test/build.gradle to build.gradle.kts #1160 => thanks to @femialaka
  • rewrite misc/tools/atrium-samples-test/build.gradle to build.gradle.kts #1161 => thanks to @Stexxe
  • rewrite the root build.gradle to build.gradle.kts and update tutteli-gradle-plugin
  • update to new dokka plugin #641
  • Builds take too long #971

samples

  • Added SequenceSubjectChangerSamples.kt with samples #1179 => thanks to @JordanllHarper
  • add ResultExpectationSamples also to api-infix #1157
  • add samples for iterableSubjectChangers to api-fluent and api-infix #1038 => thanks to @simonNozaki
  • add samples for sequenceSubjectChangers also to api-infix #1046 => thanks to @JordanllHarper

migrations

  • migrate DescriptiveWithBasedOnSubjectSpec from spek to kotest #1194 => thanks to @jakubriegel
  • migrate BulletPointProviderSpec from spek to kotest #1195 => thanks to @jakubriegel
  • migrate AtriumErrorSpec from spek to kotest #1196 => thanks to @jakubriegel
  • migrate AdjustStackSpec from spek to kotest #1201 => thanks to @Dark-Knight11
  • migrate TextSpec from spek to kotest #1197 => thanks to @Dark-Knight11
  • migrate fluent-en_GB SmokeTest from spek to kotest #1202 => thanks to @Dark-Knight11

Sadly, we had to move back to Spek for the moment as kotest is buggy in terms of the JS platform. Kotlin-test (i.e. all samples) where no longer run as soon as kotest was specified as dependency

Deprecation

  • none this time

Deprecations with 1.1.0

  • we will drop the support for internationalization with 1.2.0, all functions involving Translatable will be deprecated in v1.1.0
  • we will rename the package ch.tutteli.atrium.api.fluent.en_GB.creating.charsequence.contains to charsequence.toCtonain` and thus deprecated the existing packages (will be dropped with 1.5.0 latest) -- same same for the infix API
  • same same for iterable.toContain (fluent and infix API)
  • we will drop support for Kotlin 1.2 and deprecate the package ch.tutteli.atrium.api.fluent.en_GB.kotlin_1_3 as we move the functions to
    ch.tutteli.atrium.api.fluent.en_GB (same same for infix)
  • might be we drop en_GB from package names
  • might be we move BulletPointProvider to another package

Deprecations with 1.2.0

We will make a major refactoring on core and logic level. Those changes should not affect most Atrium users. It might affect you if you:

  • created own expectation function based on assertionBuilder or other types which are defined in core or logic.
  • use an own expectation verb

Migration steps/pointers will be provided in the release notes as usual.

The following changes are planned:

  • replace Assertion with Proof and along with it rename many types incorporating Assertion in its name or in its package's name => we will remove Assertion and co. with 1.5.0 at the latest)
  • re-write reporting entirely, a lot of types in ch.tutteli.atrium.reporting will be affected (could be we move this to 1.3.0)
  • rename StringBuilder.appendln() to appendLine (to follow kotlin)

Breaking Changes

Planned (previously deprecated or announced)

  • removed COULD_NOT_EVALUATE_DEFINED_ASSERTIONS => will be removed without replacement
  • removed VISIT_COULD_NOT_EVALUATE_ASSERTIONS => will be removed without replacement
  • removed ContainsAssertionCreator#getDescriptionContains => use descriptionToContain
  • removed InOrderOnlyReportingOptions.showOnlyFailingIfMoreElementsThan => use showOnlyFailingIfMoreElementsThan
  • removed InOrderOnlyReportingOptions.numberOfElementsInSummary => use maxNumberOfExpectedElementsForSummary
  • removed ErrorMessages enum entries which contained ASSERTION
  • removed maplike.contains.checkers.* => looks like they were introduced by accident, removed without replacement
  • removed all deprecated function/classes/interfaces/translations etc. which were marked to be removed with 1.0.0 latest

Unplanned

  • not really a breaking change but we already removed en_GB from artifact names.

Breaking Changes with 1.1.0

  • we will drop support for Kotlin 1.2 (might even drop support for kotlin 1.3)
  • we will switch from LEGACY compiler backend to IR backend for JS
  • we will use the IR compiler backend for JVM
  • we will drop support for jdk 14 (i.e. we no longer build against it, most likely it still works without problems) and officially support jdk 17
  • we will drop support for translating the output - API will persist until 1.2.0 but we might already only use UsingDefaultTranslator
  • we might introduce interface groups for ReporterBuilder - binary compatibility break

Breaking Changes with 1.2.0

  • we might drop support for kotlin 1.3 (if not already in 1.1.0)
  • BulletPointProvider will most likely use a BulletPointIdentifier from a different package

Migrating deprecated functionality

Use the ReplaceWith in the corresponding @Deprecated annotations.

Please have a look at older release-notes in case you don't migrate from 0.18.0

Sponsors

We would like to thank   Tegonal Genossenschaft (Tegonal Cooperative, Bern, Switzerland) for sponsoring the time @robstoll is working on Atrium.

Are you using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - align reporting to new `to + infinitive` schema and more reportingOptions

Published by robstoll over 2 years ago

Table of Content

New Features

All APIs

  • aligned reporting to new to + infinitive schema
  • start error message with I expected... #1090
  • also add reportOptions to inAnyOrder.only #1094

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • add report option to inGiven order and only in api-infix #1050

Logic / Core

  • not a feature as such but more a recommendation. We started to split API files into XyExpectations.kt, XyFeatureExtractor.kt and XySubjectChangers.kt -- we think it will help to get the distinction between those three categories
  • add createAndAppend to AssertionContainer expecting Translatable #1061

Fixes

  • additional elements detected wrong for inAnyOrder.only #1103

Improvements

  • include given type in error message of IterableLikeToIterableTransformer #1057
  • add samples for optionalExpectations of api-fluent #917 => thanks to @timacosta
  • add samples for featureAssertions of api-fluent #648 => thanks to @iljakorneckis
  • add samples for Map.size to api-fluent and api-infix #1039 => thanks to @ashwini-desai
  • add samples for fun0Expectations also to api-infix #1044 => thanks to @Kushiro-C
  • generate jdk11 byte code instead of jdk1.6 (see breaking changes below for more details)

Deprecation

  • ErrorMessages enum entries which contained ASSERTION => use the replacement with EXPECTATION
  • all Description...Assertion.kt => use use the replacement from Description...Expectation.kt
  • DescriptionBasic.IS => use TO_BE instead
  • DescriptionBasic.IS_NOT => use NOT_TO_BE instead
  • maplike.contains.checkers.* => looks like they were introduced by accident, they will be removed with 0.19.0 without replacement
  • COULD_NOT_EVALUATE_DEFINED_ASSERTIONS => will be removed without replacement
  • VISIT_COULD_NOT_EVALUATE_ASSERTIONS => will be removed without replacement
  • InOrderOnlyReportingOptions.showOnlyFailingIfMoreElementsThan => use showOnlyFailingIfMoreElementsThan will be removed with 0.19.0
  • InOrderOnlyReportingOptions.numberOfElementsInSummary => use maxNumberOfExpectedElementsForSummary will be removed with 0.19.0

Deprecations with 0.19.0

  • we will switch to the new MPP plugin, could be we have to deprecate a few things in this context

Deprecations with 0.20.0

We will make a major refactoring on core and logic level. Those changes should not affect most Atrium users. It will affect you if you:

  • created own expectation function based on assertionBuilder or other types which are defined in core or logic.
  • use an own expectation verb

Migration steps/pointers will be provided in the release notes as usual.

The following changes are planned:

  • replace Assertion with Proof and along with it rename many types incorporating Assertion in its name or in its package's name => we will remove Assertion and co. with 0.22.0 at the latest)
  • re-write reporting entirely, a lot of types in ch.tutteli.atrium.reporting will be affected (could be we move this to 0.21.0)

Breaking Changes

Planned (previously deprecated or announced)

  • removed the pre-defined assertion verbs assert and assertThat as they do not fit the to + infinitive naming schema => switch to expect
  • moved expectation functions already following the to + infinitive convention from ...Assertions.kt to the corresponding ...Expectations.kt file which is a binary breaking change => please re-compile your sources
  • renamed files named charSequence/iterableLike/mapLikeContains... to charSequence/iterableLike/mapLikeToContain which is a binary breaking change => please re-compile your sources
  • we will generate jdk 11 byte code (yes, we skip jdk8 as newer android versions support jdk11 byte code) an no longer jdk1.6 (and thus also rely on Kotlin's stlib-jdk8) => might affect you in case you still generate jdk1.6 or jdk1.8 in tests as inlining will not work (jdk11 code cannot be inlined into jdk1.6 or jdk1.8)

Unplanned

  • added InAnyOrderOnlyReportingOptions to inAnyOrder.only => please re-compile
  • added InOrderOnlyReportingOptions and InAnyOrderOnlyReportingOptions to inOrder.only.grouped => please re-compile
  • InOrderOnlyMatcher.addSingleEntryAssertion now expects a DescriptionIterableLikeExpectation instead of a DescriptionIterableAssertion => we guess this should not affect 99.999% of the users 😆
  • renamed WithInOrderOnlyReportingOptions.report to WithInOrderOnlyReportingOptions.options

Breaking Changes with 0.19.0

First of all, see deprecation above which will be removed with 0.19.0, some of them are breaking as well

  • we drop support for jdk 14 (i.e. we no longer build against it, most likely it still works without problems)
  • might be that we need to change package names which is a binary and source backward compatibility break in case we switch to the new Kotlin MPP plugin with 0.19.0

Breaking Changes with 0.20.0

  • BulletPointProvider will most likely use a BulletPointIdentifier from a different package

Breaking Changes with 0.21.0

  • not pre-seen for now

Breaking Changes with 0.22.0

  • we will remove all deprecated...Assertions.kt files in all APIs
  • we will remove all deprecated... files in the translation modules
  • we will remove all deprecated stuff on the logic/core level

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

Use the ReplaceWith in the corresponding @Deprecated annotations.

Please have a look at older release-notes in case you don't migrate from 0.17.0

Sponsors

We would like to thank   Tegonal GmbH (Tegonal GmbH, Bern, Switzerland) for sponsoring the time @robstoll is working on Atrium.

Are you using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - to + infinitive naming schema change

Published by robstoll almost 3 years ago

Table of Content

New Features

All APIs

  • Refactor/Renaming to a consistent to + infitive schema #840
  • notToBeGreaterThan and notToBeLessThan #878 => thanks to @jGleitz for the feature request
  • add Path.notToBeWritable #1001 => thanks to @rhushikesh for the implementation
  • add Path.notToBeExecutable #1015 => thanks to @rhushikesh for the implementation
  • add Path.notToBeReadable #942 => thanks to @botex98 for the implementation

api-fluent-en_GB

  • Add option to display only unexpected or missing elements in asserts on collections #292

api-infx-en_GB

  • no infix only additions this time

Logic / Core

  • none this time

Fixes

  • fix empty feature extractor #950

Improvements

  • Move hasNext() check out of Iterable.all #305 => thanks to @wordhou for the implementation
  • improve reporting for containsDuplicates #813 => thanks to @wordhou for the implementation
  • less verbose containsNot reporting and more hints #722 => thanks to @wordhou for the implementation
  • don't show number of occurrences for contains.inAnyOrder.atLeast(1) #310 => thanks to @wordhou for the implementation
  • rename withFailureHint to withHelpOnFailure #671 => thanks to @stevenlmcgraw for the implementation
  • show more than first line when using mocha test runner #691 => thanks to @wordhou for the implementation
  • Empty assertionCreator lambda warning is added twice #933 => thanks to @wordhou for the implementation
  • rewrite samples to use Kotlin DSL for gradle #873 => thanks to @wordhou
  • add samples for iterableExpectations of api-fluent #651 => thanks to @wordhou
  • add samples for fun0Assertions of api-fluent #650 => thanks to @szatyinadam
  • add samples for mapExpectations of api-infix #861 => thanks to @kacmacuna
  • add samples for mapEntryExpectations of api-infix #862 => thanks to @kacmacuna
  • add samples for iterableExpectations of api-infix #992 => thanks to @vinayak03
  • add samples for fileAssertions of api-fluent #994 => thanks to @iljakorneckis
  • add samples for resultExpectations of api-fluent #993 => thanks to @vinayak03
  • add samples for bigDecimalExpectations of api-fluent #904 => thanks to @timacosta
  • add samples for pathExpectations of api-fluent #919 => thanks to @kacmacuna
  • add samples for throwableExpectations of api-fluent #658 => thanks to @szatyinadam
  • add samples for infix throwable expectations #1002 => thanks to @szatyinadam
  • add samples for chronoLocalDateExpectations of api-fluent #914 => thanks to @dias-wagner
  • add samples for chronoLocalDateTimeExpectations of api-fluent #915 => thanks to @dias-wagner
  • add samples for chronoZonedDateTimeExpectations of api-fluent #916 => thanks to @dias-wagner
  • add samples for localDateAssertions of api-fluent and api-infix #996 => thanks to @rhushikesh
  • add samples for localDateTimeAssertions of api-fluent and api-infix #997 => thanks to @rhushikesh
  • add samples for zonedDateTimeAssertions of api-fluent #998 => thanks to @vinayak03
  • add samples for arrayAssertions of api-infix #675 => thanks to @szatyinadam
  • add samples for pairAssertions of api-infix #679 => thanks to @szatyinadam
  • add samples for pathExpectations of api-infix #999 => thanks to @rhushikesh
  • add samples for sequenceExpectations of api-fluent #657 => thanks to @loge1998
  • add samples for ZonedDateTime to api-infix #1019 => thanks to @iljakorneckis
  • Add ChronoLocalDate, ChronoLocalDateTime and ChronoZonedDateTime expectation samples for the infix api #941 => thanks to @dias-wagner

Deprecation

  • we deprecated the pre-defined assertion verbs assert and assertThat as they do not fit the to + infinitive naming schema; they will be removed with 0.18.0 => switch to expect
  • basically all expectation functions which did not follow the to + infinitive naming schema => see migration further below

Deprecations with 0.18.0

  • we will deprecate all translation enum entries which do not follow the to + infinitive naming schema

Deprecations with 0.19.0

We will make a major refactoring on core and logic level where we will:

  • replace Assertion with Proof and along with it rename many types incorporating Assertion in its name or in its package's name => we will remove Assertion and co. with 0.21.0 at the latest)
  • re-write reporting entirely, a lot of types in ch.tutteli.atrium.reporting will be affected (could be we move this to 0.20.0)

Those changes should not affect most Atrium users. It will affect you if you:

  • created own assertion function based on assertionBuilder or other types which are defined in core or logic.
  • use an own expectation verb

Migration steps/pointers will be provided in the release notes as usual.

Breaking Changes

Planned (previously deprecated or announced)

Unplanned

  • none this time

Breaking Changes with 0.18.0

First of all, see deprecation above which will be removed with 0.18.0, some of them are breaking as well

  • we will move expectation functions already following the to + infinitive convention from ...Assertions.kt to the corresponding ...Expectations.kt file which is a binary breaking change => please re-compile your sources
  • we will rename files named charSequence/iterableLike/mapLikeContains... to charSequence/iterableLike/mapLikeToContain which is a binary breaking change => please re-compile your sources
  • we will generate jdk 11 byte code (yes, we skip jdk8 as newer android versions support jdk11 byte code) an no longer jdk1.6 (and thus also rely on Kotlin's stlib-jdk11) => might affect you in case you still generate jdk1.6 or jdk1.8 in tests as inlining will not work (jdk11 code cannot be inlined into jdk1.6 or jdk1.8)

Breaking Changes with 0.19.0

  • BulletPointProvider will most likely use a BulletPointIdentifier from a different package
  • might be that we need to change package names which is a binary and source backward compatibility break in case we switch to the new Kotlin MPP plugin with 0.19.0

Breaking Changes with 0.20.0

  • we will remove all deprecated ...Assertions as well as other deprecating stuff on the logic level.

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

The following command is carrying out some search & replace so that you don't need to rely on the (unfortunately sometimes buggy) behaviour of ReplaceWith.

find . -type f -name "*.kt" -a \( -path "*/src/test/*" -o -path "*/src/*Test/*" \) | xargs perl -0777 -i \
-pe 's/import ch.tutteli.atrium.api.verbs.(assert|assertThat)\n/import ch.tutteli.atrium.api.verbs.expect\n/g;' \
-pe 's/(assert|assertThat)(\(| ?\{)/expect$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.toBe\n/import ch.tutteli.atrium.api.$1.en_GB.toEqual\n/g;' \
-pe 's/([\. ])toBe([\( ])/$1toEqual$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.notToBe\n/import ch.tutteli.atrium.api.$1.en_GB.notToEqual\n/g;' \
-pe 's/([\. ])notToBe([\( ])/$1notToEqual$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isSameAs\n/import ch.tutteli.atrium.api.$1.en_GB.toBeTheInstance\n/g;' \
-pe 's/([\. ])isSameAs([\( ])/$1toBeTheInstance$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNotSameAs\n/import ch.tutteli.atrium.api.$1.en_GB.notToBeTheInstance\n/g;' \
-pe 's/([\. ])isNotSameAs([\( ])/$1notToBeTheInstance$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.notToBeNull\n/import ch.tutteli.atrium.api.$1.en_GB.notToEqualNull\n/g;' \
-pe 's/([\. ])notToBeNull([\( ])/$1notToEqualNull$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isA\n/import ch.tutteli.atrium.api.$1.en_GB.toBeAnInstanceOf\n/g;' \
-pe 's/([\. ])isA</$toBeAnInstanceOf</g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNoneOf\n/import ch.tutteli.atrium.api.$1.en_GB.notToBeOneOf\n/g;' \
-pe 's/([\. ])isNoneOf([\( ])/$1notToBeOneOf$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNotIn\n/import ch.tutteli.atrium.api.$1.en_GB.notToBeIn\n/g;' \
-pe 's/([\. ])isNotIn([\( ])/$1notToBeIn$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.contains\n/import ch.tutteli.atrium.api.$1.en_GB.toContain\n/g;' \
-pe 's/([\. ])contains([\( \.])/$1toContain$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsNot\n/import ch.tutteli.atrium.api.$1.en_GB.notToContain\n/g;' \
-pe 's/([\. ])containsNot([\( \.])/$1notToContain$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsRegex\n/import ch.tutteli.atrium.api.$1.en_GB.toContainRegex\n/g;' \
-pe 's/([\. ])containsRegex([\( ])/$1toContainRegex$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.contains\n/import ch.tutteli.atrium.api.$1.en_GB.toContain\n/g;' \
-pe 's/([\. ])contains([\( ])/$1toContain$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.startsWith\n/import ch.tutteli.atrium.api.$1.en_GB.toStartWith\n/g;' \
-pe 's/([\. ])startsWith([\( ])/$1toStartWith$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.startsNotWith\n/import ch.tutteli.atrium.api.$1.en_GB.notToStartWith\n/g;' \
-pe 's/([\. ])startsNotWith([\( ])/$1notToStartWith$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.endsWith\n/import ch.tutteli.atrium.api.$1.en_GB.toEndWith\n/g;' \
-pe 's/([\. ])endsWith([\( ])/$1toEndWith$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.endsNotWith\n/import ch.tutteli.atrium.api.$1.en_GB.notToEndWith\n/g;' \
-pe 's/([\. ])endsNotWith([\( ])/$1notToEndWith$2/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isEmpty\n/import ch.tutteli.atrium.api.fluent.en_GB.toBeEmpty\n/g;' \
-pe 's/([\. ])isEmpty\(/$1toBeEmpty\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isNotEmpty\n/import ch.tutteli.atrium.api.fluent.en_GB.notToBeEmpty\n/g;' \
-pe 's/([\. ])isNotEmpty\(/$1notToBeEmpty\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isNotBlank\n/import ch.tutteli.atrium.api.fluent.en_GB.notToBeBlank\n/g;' \
-pe 's/([\. ])isNotBlank\(/notToBeBlank\(/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.matches\n/import ch.tutteli.atrium.api.$1.en_GB.toMatch\n/g;' \
-pe 's/([\. ])matches([\( ])/$1toMatch$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.mismatches\n/import ch.tutteli.atrium.api.$1.en_GB.notToMatch\n/g;' \
-pe 's/([\. ])mismatches([\( ])/$1notToMatch$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.hasSize\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveSize\n/g;' \
-pe 's/([\. ])hasSize([\( ])/$1toHaveSize$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isLessThan\n/import ch.tutteli.atrium.api.$1.en_GB.toBeLessThan\n/g;' \
-pe 's/([\. ])isLessThan([\( ])/$1toBeLessThan$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isLessThanOrEqual\n/import ch.tutteli.atrium.api.$1.en_GB.toBeLessThanOrEqualTo\n/g;' \
-pe 's/([\. ])isLessThanOrEqual([\( ])/$1toBeLessThanOrEqualTo$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isGreaterThan\n/import ch.tutteli.atrium.api.$1.en_GB.toBeGreaterThan\n/g;' \
-pe 's/([\. ])isGreaterThan([\( ])/$1toBeGreaterThan$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isGreaterThanOrEqualTo\n/import ch.tutteli.atrium.api.$1.en_GB.toBeGreaterThanOrEqualTo\n/g;' \
-pe 's/([\. ])isGreaterThanOrEqual([\( ])/$1toBeGreaterThanOrEqual$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isEqualComparingTo\n/import ch.tutteli.atrium.api.$1.en_GB.toBeEqualComparingTo\n/g;' \
-pe 's/([\. ])isEqualComparingTo([\( ])/$1toBeEqualComparingTo$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.toBeWithErrorTolerance\n/import ch.tutteli.atrium.api.$1.en_GB.toEqualWithErrorTolerance\n/g;' \
-pe 's/([\. ])toBeWithErrorTolerance([\( ])/$1toEqualWithErrorTolerance$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsExactly\n/import ch.tutteli.atrium.api.$1.en_GB.toContainExactly\n/g;' \
-pe 's/([\. ])containsExactly([\( ])/$1toContainExactly$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsExactlyElementsOf\n/import ch.tutteli.atrium.api.$1.en_GB.toContainExactlyElementsOf\n/g;' \
-pe 's/([\. ])containsExactlyElementsOf([\( ])/$1toContainExactlyElementsOf$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsElementsOf\n/import ch.tutteli.atrium.api.$1.en_GB.toContainElementsOf\n/g;' \
-pe 's/([\. ])containsElementsOf([\( ])/$1toContainElementsOf$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.any\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveElementsAndAny\n/g;' \
-pe 's/([\. ])any([\( ])/$1toHaveElementsAndAny$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.none\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveElementsAndNone\n/g;' \
-pe 's/([\. ])none([\( ])/$1toHaveElementsAndNone$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.all\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveElementsAndAll\n/g;' \
-pe 's/([\. ])all([\( ])/$1toHaveElementsAndAll$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.all\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveElementsAndAll\n/g;' \
-pe 's/([\. ])all([\( ])/$1toHaveElementsAndAll$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsNoDuplicates\n/import ch.tutteli.atrium.api.$1.en_GB.toHaveElementsAndNoDuplicates\n/g;' \
-pe 's/([\. ])containsNoDuplicates([\( ])/$toHaveElementsAndNoDuplicates$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsOnly\n/import ch.tutteli.atrium.api.$1.en_GB.toContainOnly\n/g;' \
-pe 's/([\. ])containsOnly([\( ])/$1toContainOnly$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsEntriesOf\n/import ch.tutteli.atrium.api.$1.en_GB.toContainEntriesOf\n/g;' \
-pe 's/([\. ])containsEntriesOf([\( ])/$1toContainEntriesOf$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsOnlyEntriesOf\n/import ch.tutteli.atrium.api.$1.en_GB.toContainOnlyEntriesOf\n/g;' \
-pe 's/([\. ])containsOnlyEntriesOf([\( ])/$1toContainOnlyEntriesOf$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsKey\n/import ch.tutteli.atrium.api.$1.en_GB.toContainKey\n/g;' \
-pe 's/([\. ])containsKey([\( ])/$1toContainKey$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.containsNotKey\n/import ch.tutteli.atrium.api.$1.en_GB.notToContainKey\n/g;' \
-pe 's/([\. ])containsNotKey([\( ])/$1notToContainKey$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isKeyValue\n/import ch.tutteli.atrium.api.$1.en_GB.toEqualKeyValue\n/g;' \
-pe 's/([\. ])isKeyValue([\( ])/$1toEqualKeyValue$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.messageContains\n/import ch.tutteli.atrium.api.$1.en_GB.messageToContain\n/g;' \
-pe 's/([\. ])messageContains([\( ])/$1messageToContain$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNumericallyEqualTo\n/import ch.tutteli.atrium.api.$1.en_GB.toEqualNumerically\n/g;' \
-pe 's/([\. ])isNumericallyEqualTo([\( ])/$1toEqualNumerically$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNotNumericallyEqualTo\n/import ch.tutteli.atrium.api.$1.en_GB.notToEqualNumerically\n/g;' \
-pe 's/([\. ])isNotNumericallyEqualTo([\( ])/$1notToEqualNumerically$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isEqualIncludingScale\n/import ch.tutteli.atrium.api.$1.en_GB.toEqualIncludingScale\n/g;' \
-pe 's/([\. ])isEqualIncludingScale([\( ])/$1toEqualIncludingScale$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isNotEqualIncludingScale\n/import ch.tutteli.atrium.api.$1.en_GB.notToEqualIncludingScale\n/g;' \
-pe 's/([\. ])isNotEqualIncludingScale([\( ])/$1notToEqualIncludingScale$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isBefore\n/import ch.tutteli.atrium.api.$1.en_GB.toBeBefore\n/g;' \
-pe 's/([\. ])isBefore([\( ])/$1toBeBefore$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isBeforeOrEqual\n/import ch.tutteli.atrium.api.$1.en_GB.toBeBeforeOrTheSamePointInTimeAs\n/g;' \
-pe 's/([\. ])isBeforeOrEqual([\( ])/$1toBeBeforeOrTheSamePointInTimeAs$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isAfter\n/import ch.tutteli.atrium.api.$1.en_GB.toBeAfter\n/g;' \
-pe 's/([\. ])isAfter([\( ])/$1toBeAfter$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isAfterOrEqual\n/import ch.tutteli.atrium.api.$1.en_GB.toBeAfterOrTheSamePointInTimeAs\n/g;' \
-pe 's/([\. ])isAfterOrEqual([\( ])/$1toBeAfterOrTheSamePointInTimeAs$2/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isEqual\n/import ch.tutteli.atrium.api.$1.en_GB.toBeTheSamePointInTimeAs\n/g;' \
-pe 's/([\. ])isEqual([\( ])/$1toBeTheSamePointInTimeAs$2/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isPresent\n/import ch.tutteli.atrium.api.fluent.en_GB.toBePresent\n/g;' \
-pe 's/([\. ])isPresent\(/$1toBePresent\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isSuccess\n/import ch.tutteli.atrium.api.fluent.en_GB.toBeASuccess\n/g;' \
-pe 's/([\. ])isSuccess\(/$1toBeASuccess\(/g;' \
-pe 's/import ch.tutteli.atrium.api.infix.en_GB.success\n/import ch.tutteli.atrium.api.infix.en_GB.aSuccess\n/g;' \
-pe 's/toBe\(success\)/toBe\(aSuccess\)/g;' \
-pe 's/toBe success \{/toBe aSuccess \{/g;' \
-pe 's/import ch.tutteli.atrium.api.(fluent|infix).en_GB.isFailure\n/import ch.tutteli.atrium.api.$1.en_GB.toBeAFailure\n/g;' \
-pe 's/([\. ])isFailure([\( ])/$1toBeAFailure$2/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.exists\n/import ch.tutteli.atrium.api.fluent.en_GB.toExist\n/g;' \
-pe 's/([\. ])exists\(/$1toExist\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.existsNot\n/import ch.tutteli.atrium.api.fluent.en_GB.notToExist\n/g;' \
-pe 's/([\. ])existsNot\(/$1notToExist\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.is(Readable|Writable|Executable|Absolute|Relative)\n/import ch.tutteli.atrium.api.fluent.en_GB.toBe$1\n/g;' \
-pe 's/([\. ])is(Readable|Writable|Executable|Absolute|Relative)\(/$1toBe$2\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.is(RegularFile|Directory|SymbolicLink)\n/import ch.tutteli.atrium.api.fluent.en_GB.toBeA$1\n/g;' \
-pe 's/([\. ])is(RegularFile|Directory|SymbolicLink)\(/$1toBeA$2\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.isEmptyDirectory\n/import ch.tutteli.atrium.api.fluent.en_GB.toBeAnEmptyDirectory\n/g;' \
-pe 's/([\. ])isEmptyDirectory\(/$1toBeAnEmptyDirectory\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.hasDirectoryEntry\n/import ch.tutteli.atrium.api.fluent.en_GB.toHaveTheDirectoryEntries\n/g;' \
-pe 's/([\. ])hasDirectoryEntry\(/$1toHaveTheDirectoryEntries\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.hasSameTextualContentAs\n/import ch.tutteli.atrium.api.fluent.en_GB.toHaveTheSameTextualContentAs\n/g;' \
-pe 's/([\. ])hasSameTextualContentAs\(/$1toHaveTheSameTextualContentAs\(/g;' \
-pe 's/import ch.tutteli.atrium.api.fluent.en_GB.hasSameBinaryContentAs\n/import ch.tutteli.atrium.api.fluent.en_GB.toHaveTheSameBinaryContentAs\n/g;' \
-pe 's/([\. ])hasSameBinaryContentAs\(/$1toHaveTheSameBinaryContentAs\(/g;'

It might well be that the above commands replace a bit too much in certain cirumstances (e.g. if you use Kotlin's all, any or none in tests or startsWith, endsWith etc.) - we guess that reverting those cases is still faster than applying suggestions manually. Feel free to remove the corresponding problematic lines and use the replacements for those cases instead.

The above command does not include the replacement of hasNext and hasNotNext as the replacement is depending on the type of the subject of the assertion. Please use the suggested replacements in the @Deprecated annotation.

Please have a look at older release-notes in case you don't migrate from 0.12.0 - 0.16.0

Sponsors

We would like to thank Tegonal GmbH for sponsoring Support and PR-Review time.
And also a big thank you for sponsoring some time to speed up the transition to the new to + infitive naming schema 🙃

Are you are using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - to + infinitive naming schema change - please test migration

Published by robstoll over 3 years ago

Official release notes will be done with v0.17.0 (see https://github.com/robstoll/atrium/wiki/Release-notes-0.17.0-draft in the meantime)

atrium - Path.isSymbolicLink/isEmptyDirecty, `its` and logic/core refactorings

Published by robstoll over 3 years ago

Table of Content

New Features

All APIs

  • #765 Path.isSymbolicLink => thanks to @fimbulwint for the implementation
  • #766 Path.isEmptyDirectory => thanks to @mai2412 for the implementation
  • #837 introduce its as convenience feature extractor at the cost of poorer reporting

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • no infix only additions this time

Logic / Core

  • #586 refactor core, don't use ServiceLoader
    • introduced experimental ComponentFactoryContainer which replaces the current ServiceLoader approach
    • moved most functionality from core-robstoll-lib to atrium-api-core (though in impl packages and not exposed via module-info, create an issue if you have the need to use an implementation directly)

Fixes

  • #771 contains all no longer working in infix
  • #777 containsNoDuplicate reports has duplicates => reports now has not: duplicate elements

Improvements

  • #677 add samples for iteratorAssertions of api-infix => thanks to @lilimapradhan9
  • #678 add samples for listAssertions of api-infix => thanks to @lilimapradhan9 and thanks to @szatyinadam for a fix
  • #676 add samples for comparableAssertions of api-infix => thanks to @mai2412
  • #680 add samples for collectionAssertions of api-infix => thanks to @szatyinadam
  • #741 Improve the Documentation for because => thanks to @jGleitz
  • #742 Remove ‘@throws AssertionError’ KDoc from Assertion Functions => thanks to @jGleitz
  • #756 create PR with generated README examples on master if necessary
  • #746 Change Wording from ‘Assertion’ to ‘Expectation’ => thanks to @jGleitz for the idea and part of the work
  • #806 filter out io.kotest runner from RemoveRunnerAtriumError => thanks to @mai2412 for the implementation
  • #803 don't depend on jcenter

Deprecation

  • VarArgHelper, Group, and helper functions in package ch.tutteli.atrium.domain.builders.utils; they will all be removed with 0.17.0 => use the equivalent from atrium-logic (search & replace import)
  • moved PleaseUseReplacementException from domain-builders to core
  • evalOnce; will be removed with 0.17.0 without replacement.
  • SubjectProvider; will be removed with 0.17.0 without replacement. => use Expect on the API level and AssertionContainer on the logic level
  • AssertionBuilder.createDescriptive => use _logic.createDescriptiveAssertion instead
  • AssertionContainer.collectForDifferentSubject => use collectBasedOnDifferentSubject
  • FeatureExpectOptionsChooser from atrium-core => use the one from atrium-logic instead
  • Reporter.atriumErrorAdjuster; will be removed with 0.17.0 => use ComponentFactoryContainer instead
  • MethodCallFormatter.format; will be removed with 0.17.0 => use formatCall
  • Feature.description and FeatureWithCreator.description in api-infix; will be removed with 0.17.0 => use descriptionProvider instead
  • ReporterFactory and reporter => use ComponentFactoryContainer instead
  • ReporterBuilder including all steps => use ComponentFactoryContainer instead
  • ExpectBuilder including all steps => use RootExpectBuilder from atrium-logic
  • MetaFeature; will be removed with 0.17.0 => use MetaFeature from atrium-logic
  • MetaFeatureBuilder; will be removed with 0.17.0 without replacement
  • MetaFeatureOption; will be removed with 0.17.0 => use MetaFeatureOption from the API

Deprecations with 0.17.0

Basically all assertion functions in api-fluent (and maybe also in api-infix) as we move to a consistent to + infinitive naming schema in api-fluent. We might deprecate all translation enum entries which do not follow the to+infinitive schema but since we plan to rename those in 0.18.0 anyway, we might also wait until then.

Breaking Changes

Planned (previously deprecated or announced)

see #755

  • removed deprecated APIS and bundles
  • removed deprecated functions in domain-api, domain-robstoll, domain-robstoll-lib and domain-builders
  • removed deprecated atrium-spec
  • removed other deprecated modules

moreover:

  • #773 we do no longer build against jdk 9, jdk10, jdk12, jdk13 or in other words we drop support for those versions => update to jdk 11 or stick with jdk8
  • removed AssertionHolder -> changed DelegatingExpect accordingly, expects now an AssertionContainer
  • removed DescriptionMapAssertion
  • parameter objects extending Group from domain-builders now extend Group from builders => binary backward compatibility break - most likely you will not notice anything. If you should have used own types extending Group, then switch to atrium-logic as well.
  • we removed deprecated ...Assertions as well as other deprecating stuff on the logic level.

Unplanned

  • removed stuff in core as well, which was already deprecated and only used by the above deprecated functionality. This was not announced prior but we doubt that someone will be affected.
  • made BasicAssertionGroup, ExplanatoryAssertionGroup, InvisibleAssertionGroup, BasicExplanatoryAssertion, BasicDescriptiveAssertion and EmptyNameAndRepresentationAssertionGroup internal
  • removed deprecated translations which were scheduled to be removed with 1.0.0, we kept them long enough.
  • made constructor of ArgumentMapperBuilder internal => use mapArguments instead
  • moved MetaFeature to atrium-logic and MetaFeatureOption to the APIs, this is a binary backward compatible break only => please re-compile.

Breaking Changes with 0.17.0

First of all, see deprecation above which will be removed with 0.17.0, some of them are breaking as well

  • we will remove RawString => switch to Text
  • we will remove StringBasedRawString => switch to Text
  • we will remove Untranslatable.constructor which expect CharSequence and a lambda => use the primary constructor which expects a string
  • we will remove Feature.description and FeatureWithCreator.description in api-infix => use descriptionProvider instead
  • we will remove domain-builders => switch to atrium-logic
  • we will remove domain-robstoll and domain-robstoll-lib => switch to atrium-logic
  • we will remove core-robstoll => create components via ComponentFactoryContainer (still experimental currently thought)
  • we will remove core-robstoll-lib => implementation is now part of core
  • not really a breaking change but just as info, we will most likely rename core-api to core (as we no longer split core into api and implementation)
  • might be that we need to change package names which is a binary and source backward compatibility break in case we switch to the new Kotlin MPP plugin with 0.17.0

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

The following command is carrying out some search & replace so that you don't need to rely on the (unfortunately sometimes buggy) behaviour of ReplaceWith.

find ./ -path "*/test/*" -name "*.kt" | xargs perl -0777 -i \
-pe 's/import ch.tutteli.atrium.domain.builders.utils/import ch.tutteli.atrium.logic.utils/g;' 

Please have a look at older release-notes in case you don't migrate from 0.12.0 - 0.15.0

Sponsors

We would like to thank Tegonal GmbH for sponsoring Support and PR-Review time.

Are you are using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your expectation functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - MapLike.contains

Published by robstoll almost 4 years ago

Table of Content

New Features

All APIs

  • #173 MapLike.contains including sophisticated builder (also for inOrder.only)
  • #68 MapLike.containsOnly
  • #733 MapLike.size
  • #660 add Expect.because to document the reason for an assertion => thanks to @Valefant for most of the implementation and @jGleitz for the proposition and discussion.

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • no infix only additions this time

Logic / Core

  • #711 turn MapAssertions into MapLikeAssertions

Fixes

  • #719 fix link to examples in README

Improvements

  • #717 reword entry in reporting of Iterable.contains to element
  • #720 don't show the feature value in an explanatory assertion group
  • #736 don't show the down-cast in toBeNullIfNullGivenElse
  • #738 use the info bullet point for unexpected Exceptions
  • #739 use info bullet point for notice in BigDecimal.isEqualIncludingScale
  • add link to output of examples in README
  • list third-party extensions in README => create a pull request if you are a maintainer of an extension, we happily add yours as well.

Breaking Changes

Planned (previously deprecated or announced)

  • none this time

Unplanned

  • none this time

Deprecation

  • AnyAssertions.toBeNull on the logic level; will be removed with 0.16.0 => use toBe(null)
  • DescriptionMapAssertion; will be removed with 0.16.0 => use DescriptionMapLikeAssertion

Deprecations with 0.16.0

Breaking Changes with 0.16.0

  • we will remove all deprecated APIs (you need to migrate to api-fluent or api-infix if you want to use this version or onwards, see older release notes for migration hints and scripts).
  • we will also remove deprecated stuff on the domain/core level where they only remained due to the deprecated APIs.
  • remove AnyAssertions.toBeNullIfNullGivenElse which expects a kClass => use the one which does not
  • might be we have to break compatibility when we deprecate core-robstoll and core-robstoll-lib
  • might also be, that we have to break compatibility when we move ExpectBuilder and ExpectOptions from domain-builders to atrium-logic
  • we will break binary compatibility when we move Group from atrium-domain-builders to atrium-logic (or to the individual APIs)
  • we will break binary compatibility when we move VarArgHelper from atrium-domain-builders to atrium-logic
  • we might skip the process of deprecating stuff on the logic level. We will rename ...Assertions to ...Expectations
  • we will rename files on the API level which is a binary break
  • might be that we need to change package names which is a binary and source backward compatibility break in case we switch to the new Kotlin MPP plugin with 0.16.0
  • we will drop support for Java 9 and 10 (we will build 0.16.0 with jdk11) => update to jdk 11 or stick with jdk8
  • we will no longer check if compatible with jdk 12 or 13 => use jdk11 (or jdk14 but we will move to jdk15 as soon as jacoco supports it)

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

We provide @Deprecated annotations with ReplaceWith -> use the suggestions as advertised.

Please have a look at older release-notes in case you don't migrate from 0.12.0, 0.13.0 or 0.14.0

Sponsors

We would like to thank Tegonal GmbH for sponsoring Support and PR-Review time.

Are you are using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your assertion functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - Path assertions and ZonedDateTime as string

Published by robstoll almost 4 years ago

Table of Content

New Features

All APIs

  • #461 Sequence.asList => thanks to @Valefant for the implementation
  • #462 Iterable.asList => thanks to @Valefant for the implementation
  • #172 Iterable.containsNoDuplicates => thanks to @frikit for the implementation
  • #480 accept date as string in ISO 8601 format for ChronoLocalDate => thanks to @Valefant for implementation
  • #482 accept date and time as string in ISO 8601 for ChronoZonedDateTime => thanks to @Valefant for implementation
  • #591 Path.isExecutable => thanks to @jGleitz for the implementation
  • #629 Path.isAbsolute => thanks to @jakubriegel for the implementation
  • #630 Path.isRelative => thanks to @jakubriegel for the implementation
  • #590 Path.hasDirectoryEntry => thanks to @jgrgt for the first implementation (api-fluent) and @jGleitz for the completion (generalise to logic and add to infix)

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • no infix only additions this time

Domain / Core

  • we transition away from atrium-domain-... to atrium-logic, getting rid of ServiceLoader and other changes. Some parts of domain were already deprecated (see below)

Fixes

  • #631 Atrium stops working for JS with Kotlin 1.4 => thanks to @chadmarchand for the fix

Improvements

  • #628 Report Evaluation Result After notToThrow(), catch exceptions in feature extraction
  • #329 fuse FeatureAssertionSpec with AssertionSpec => thanks to @tarczynskitomek for the first few adjustments
  • #349 configure dependabot to update samples => thanks to @uzilan for the implementation
  • #400 check if Js isIntance bug is really fixed in Kotlin => thanks to @Valefant for the time and simplification
  • #409 limit representation to 10'000 chars => thanks to @Valefant for the implementation
  • #600 make generateLogic more readable with named matches => thanks to @jgrgt for the suggestion and implementation
  • #637 update gradle wrapper => thanks to @fejd
  • #473 update js samples to use the new org.jetbrains.kotlin.js gradle plugin => thanks to @chadmarchand for most of the work
  • #643 add samples for anyAssertions => thanks to @jdornieden
  • #644 add samples for arrayAssertions => thanks to @jdornieden
  • #646 add samples for collectionAssertions => thanks to @Gosunet
  • #647 add samples for comparableAssertions => thanks to @Gosunet
  • #649 add samples for floatingPointAssertions => thanks to @BimuratMukhtar
  • #652 add samples for iteratorAssertions => thanks to @Gosunet
  • #653 add samples for listAssertions => thanks to @BimuratMukhtar
  • #656 add samples for pairAssertions => thanks to @BimuratMukhtar

Breaking Changes

Planned (previously deprecated or announced)

  • we are no longer using the builders defined in the API for CharSequence/Iterable.contains but the new ones from atrium-logic. This constitutes a binary backward compatibility break. Please re-compile, it is still source compatible.

Unplanned

  • we are no longer using the builders defined in atrium-domain-builders for a subject change and feature extraction but the once from atrium-logic. This constitutes a binary backward compatibility break. Please re-compile, it is still source compatible.

Deprecation

  • the helper function asExpect to turn an Assert<T> into an Expect<T> => time to move on 😉
  • most of the module atrium-domain-builders -> use atrium-logic instead, see migration hints further down below. Inter alia:
    • SubjectChanger and SubjectChangerBuilder
    • FeatureExtractor and FeatureExtractorBuilder
    • toVarArg, iterableLikeToIterable
    • nullable, nullableContainer, nullableKeyMap etc.
    • mapArguments

Breaking Changes with 0.15.0

  • might be we have to break compatibility when we deprecate core-robstoll and core-robstoll-lib
  • might also be, that we have to break compatibility when we move ExpectBuilder and ExpectOptions from domain-builders to atrium-logic
  • we will break binary compatibility when we move Group from atrium-domain-builders to atrium-logic (or to the individual APIs)
  • we will break binary compatibility when we move VarArgHelper from atrium-domain-builders to atrium-logic

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

We don't provide ReplaceWith to transition from atrium-domain-robstoll/-robstoll-lib to atrium-logic in all cases. We don't expect that there are enough users using types of those modules directly. Let us know if you do and have troubles migrating.

In case you should use:

  • mapArguments, then search for import ch.tutteli.atrium.domain.builders.utils.mapArguments and replace it with import ch.tutteli.atrium.logic.utils.mapArguments
  • nullable, then search for import ch.tutteli.atrium.domain.builders.utils.nullable and replace with import ch.tutteli.atrium.logic.utils.nullable
  • subExpect, then search for subExpect and replace with expectLambda and search for import ch.tutteli.atrium.domain.builders.utils.subExpect and replace with import ch.tutteli.atrium.logic.utils.expectLambda

Some further search&replace patterns for assertion writers, in case you use:

  • CharSequenceOrNumberOrChar or CharSequenceOrNumberOrChar, search for import ch.tutteli.atrium.domain.creating.typeutils and replace with import ch.tutteli.atrium.logic.creating.typeutils

In case you already started using the experimental atrium-logic module, then you might run into the problem that:

  • getExpectOfFeature() does not exist => replace with transform()
  • addToInitial does not exist => replace with collectAndAppend
  • we removed genericSubjectBasedFeature and genericFeature from FeatureAssertions -> use either manualFeature or FeatureExtractor/FeatureExtractorBuilder instead

Please have a look at the older release-notes in case you don't migrate from 0.12.0 or 0.13.0

Sponsors

We would like to thank Tegonal GmbH for sponsoring Support and PR-Review time.

Are you are using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • share your assertion functions with others
  • report bugs
  • provide feedback in case you miss a feature
atrium - isEqualComparingTo, isNoneOf and string based LocalDateTime

Published by robstoll about 4 years ago

Table of Content

New Features

All APIs

  • #460 add Iterator.hasNext/hasNotNext => thanks to @mspear for the implementation
  • #484 introduce Comparable.isEqualComparingTo => thanks to @jaibhavaya for the implementation
  • #180 Any.isNoneOf/isNotIn=> thanks to @anesabml for the implementation
  • #479 Allow that Sequence and Array can be passed to elementsOf => thanks to @anesabml for the implementation
  • #481 accept date and time as string in ISO 8601 format for ChronoLocalDateTime => thanks to @rkiselev for the implementation of the fluent API

api-fluent-en_GB

  • no fluent only additions this time

api-infx-en_GB

  • Path.hasSameTextualContentAs added to infix API as well => thanks to @z13z for most of the work

Domain / Core

  • we transition away from atrium-domain-... to atrium-logic, getting rid of ServiceLoader and other changes. Some parts of domain where already deprecated. Stay tuned, documentation will be updated with 0.14.0

Fixes

  • #515 Path assertions use wrong description

Improvements

  • #234 remove limit of stacktrace
  • #483 adjust reporting for isLess/GreaterThanOrEqual => thanks to @z13z for the implementation
  • #477 deprecate defaultTranslationOf(IgnoringCase) => thanks to @z13z for the implementation
  • #337 filter jasmine out of error-stacks => thanks to @z13z for part of the work

Breaking Changes

Planned (previously deprecated or announced)

  • none this time

Unplanned

  • we are treating Translatable now special in the ObjectFormatter which does not make it necessary to wrap it into a RawString. This is a breaking change depending on how you have defined your Translatable. In case it was an Enum and you formatted it without wrapping it into a RawString, then it is now translated instead. I assume this should never be the case, so this breaking change is only hypothetical.
  • removed ch.tutteli.atrium.assertions.builders.Explanatory.ExplanationOption#withExplanation(ch.tutteli.atrium.reporting.translating.Translatable) because Translatables are now treated as Text in any case -- this is a binary backward compatibility break, it should suffice to re-compile.
  • removed ch.tutteli.atrium.domain.builders.creating.changers.FeatureExtractorBuilder.RepresentationInCaseOfFailureStep#withRepresentationForFailure(ch.tutteli.atrium.reporting.translating.Translatable) for the same reason
  • removed previousExpect and getAssertions() from FeatureExpect => let me know in case you used it
  • removed experimental config from RootExpect and FeatureExpect

Deprecation

  • Feature/RootExpectConfig; ; will be removed with 1.0.0
  • CoreFactory... (will all be removed with 1.0.0)
    • newDelegatingReportingAssertionContainer
    • newFeatureExpect
    • newReportingAssertionContainer
    • newCollectingAssertionContainer
  • RawString; will be removed with 1.0.0 -> use Text
  • StringBasedRawString; will be removed with 1.0.0 -> use Text
  • TranslatableBasedRawString; will be removed with 1.0.0 -> no longer required, use Translatable directly
  • ReportingAssertionContainer including factory methods; will be removed with 1.0.0 -> use RootExpect, FeatureExpect or DelegatingExpect instead
  • AssertionChecker and all its variants including factory methods; will be removed with 1.0.0 -> use RootExpect, FeatureExpect or DelegatingExpect instead
  • ch.tutteli.atrium.translations.ErrorMessages -> use ch.tutteli.atrium.creating.ErrorMessages instead
  • ch.tutteli.atrium.domain.robstoll.lib.creating.throwable.thrown.creators.ThrowableThrownFailureHandler -> use ch.tutteli.atrium.logic.impl.creating.changers.ThrowableThrownFailureHandler instead
  • the modules atrium-domain-robstoll and atrium-domain-robstoll-lib -> use atrium-logic instead
  • all assertion interfaces in domain-api except for CharSequence/IterableAssertions, they will be deprecated in 0.14.0
    • correspondingly all builders in domain-builders, impl classes in domain-robstoll and impl functions in domain-robstoll-lib (basically almost everything in domain-robstoll and domain-robstoll-lib is deprecated -> use atrium-logic instead)

Breaking Changes with 0.14.0

  • we are going to replace IterableContains with IterableLikeContains, this is a binary backward compatibility break. Source compatibility should still hold. IterableLikeContains will path the way to use it with Array types.
  • we are going to replace CharSequenceContains from domain with CharSequence from logic, this is a binary backward compatibility break. Source compatibility should still hold.
  • the new module atrium-logic introduced with this version is not stable yet, we most likely break things with 0.14.0. Planned is to replace CollectionAssertions with CollectionLikeAssertions.

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

There a few deprecations in this version (see above) --
use the ReplaceWith provided in the @Depreacted annotations.

Please have a look at the older release-notes in case you don't migrate from 0.12.0

Sponsors

We would like to thank Tegonal GmbH for sponsoring Support and PR-Review time as well as the extra hours to finish the open PRs which should made it into v0.13.0.

Are you are using Atrium at work?

Please consider to support the project as well by:

  • sponsoring robstoll (Author and main contributor)
  • report bugs
  • share your assertion functions with others
atrium - new infix API based on Expect instead of Assert

Published by robstoll over 4 years ago

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 and experimental features. 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-fluent-en_GB

  • #375 Path.hasSameTextualContentAs => @thanks to tkech17

new api-infix-en_GB

Thanks to the following contributors to support the migration from cc-infix-en_GB to infix-en_GB:

  • #227 collectionAssertions => thanks to @ratkayandras
  • #231 pairAssertions => thanks to @dexpota
  • #228 listAssertions => thanks to @sanatik
  • #232 sequenceAssertions => thanks to @ivanmiklec
  • #229 mapAssertions => thanks to @jlundhol
  • #230 mapEntryAssertions => thanks to @johnGachihi
  • #226 arrayAssertions => thanks to @isfedorov
  • #233 bigDecimalAssertions => thanks to @isfedorov
  • #236 create bundles for the new infix API => thanks to @isfedorov
  • #316 fileAssertions => thanks to @jGleitz
  • #317 localDateAssertions => thanks to @jGleitz
  • #318 localDateTimeAssertions => thanks to @jGleitz
  • #319 zonedDateTimeAssertions=> thanks to @tfesenko
  • #313 chronoLocalDateAssertions => thanks to @ivanmiklec
  • #314 chronoLocalDateTimeAssertions => thanks to @isfedorov
  • #315 chronoZonedDateTimeAssertions => thanks to @tfesenko
  • #388 optionalAssertions => thanks to @isfedorov

kotlin 1.3 extensions

  • #389 resultAssertions => thanks to @ivanmiklec

Domain / Core

  • none this time

Fixes

  • none this time

Improvements

  • #235 setup code coverage for windows=> thanks to @ivanmiklec
  • #245 Build samples as composite build => thanks to @assaflei
    #/167 compile android class files into dex bytecode => thanks to @assaflei
  • #493 merge jdk8 extension into jvm module => thanks to @assaflei
  • #470 create maven sample project => thanks to @binkley
  • #466 fail if a TranslatableWithArgs has not exact arguments => thanks to @tkech17
  • #495 cache gradle and dependencies in github actions => thanks to @assaflei
  • #506 remove android jars -> they are no longer required => thanks to @ultraon for checking if the module-info.class bug was really resolved in d8

Breaking Changes

Planned (previously deprecated or announced)

  • none this time (yet we no longer publish a dedicated -android jar you can use the regular jvm artifact instead)

Unplanned

  • none this time

Deprecation

The following was deprecated and will be removed with 1.0.0:

  • API cc-infix-en_GB => use infix-en_GB, fluent-en_GB respectively => a big thank you to @Miftahunajat for the many ReplaceWith he placed all over api-cc-infix to ease the migration 👍
  • the jdk8 extension was merged into the normal module => search import ch.tutteli.atrium.api.fluent.en_GB.jdk8 replace with import ch.tutteli.atrium.api.fluent.en_GB

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

API fluent

There aren't any deprecations in api-fluent-en_GB in this version and thus also no migration required if you update from 0.9.x, 0.10.0 or 0.11.0

In case you used the jdk8 extension: it was merged into the main artifact:

  • perform a search for import ch.tutteli.atrium.api.fluent.en_GB.jdk8 and replace with import ch.tutteli.atrium.api.fluent.en_GB
  • remove the corresponding dependency

API infix

You should migrate from api-cc-infix-en_GB to the new api-infix-en_GB (api-cc-infix-en_GB will be removed with 1.0.0)
In case you migrate from a version < 0.7.0 to this version, then please have a look at the migration guide given in the Release notes of v0.7.0 and v0.8.0 first.

Otherwise you can use the suggested replacements (ALT + Enter -> Replace with ...) or the search/replace patterns shown below (recommended, since faster).

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 14 as described below. The script for 15a or 15b follows afterwards (don't forget to do the manual points 16, 17, ...), 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 ./ -path "*/test/*" -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/(\.| )((?:toThrow|isA)<.*>)\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\.infix\.en_GB/import ch.tutteli.atrium.api.infix.en_GB/g;' \
-pe 's/is(Less|Greater)OrEquals/is$1ThanOrEqual/g;' \
-pe 's/\.asIterable\(\)/ asList o/g;' \
-pe 's/asIterable(\s*\{)/asList$1/g;' \
-pe 's/\.asEntries\(\)/ asEntries o/g;' \
-pe 's/ o / it /g;' \
-pe 's/get\s*Index\(([^\)]+)\)\s*assertIt\s*\{([^\}]+)\}/get index($1) {$2}/g;' \
-pe 's/import ch.tutteli.atrium.api.infix.en_GB.Index/import ch.tutteli.atrium.api.infix.en_GB.index/g;' \
-pe 's/getExisting\s*Key\(([^\)]+)\)\s*assertIt\s*\{([^\}]+)\}/getExisting key($1) {$2}/g;' \
-pe 's/import ch.tutteli.atrium.api.infix.en_GB.Key/import ch.tutteli.atrium.api.infix.en_GB.key/g;' 

In case you use Kotlin 1.4 or have enabled the new type inference, then you can use the following script to carry out point 13a:

find ./ -path "*/test/*" -name "*.kt" | xargs perl -0777 -i \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)/$1its feature of(\{ f(it::$2) \})$3/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)/feature of(\{ f(it::$1) \})$2/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)/$1its feature \{ f(it::$2) \}/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)/feature \{ f(it::$1) \}/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)/$1its feature of($2::$3)$4/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)/feature of($1::$2)$3/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)/$1 its feature($2::$3)/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)/feature($1::$2)/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)/$1its feature of($2::$3)/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)/feature of($1::$2)/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)/$1its feature of("$2.$3") { $2.$3 }/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;' \

Otherwise you need to carry out the point 13b which can be done with the following script`

find ./ -path "*/test/*" -name "*.kt" | xargs perl -0777 -i \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)/$1its feature \{ f(it::$2) \} it$3/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)/feature \{ f(it::$1) \} it$2/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)/$1its feature \{ f(it::$2) \}/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)/feature \{ f(it::$1) \}/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)/$1its feature of($2::$3)$4/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)/feature of($1::$2)$3/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)/$1 its feature($2::$3)/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)/feature($1::$2)/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)/$1its feature of($2::$3)/g;' \
-pe 's/(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)/feature of($1::$2)/g;' \
-pe 's/((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)/$1its feature of("$2.$3") { $2.$3 }/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;'

But you still need to add manually import ch.tutteli.atrium.api.infix.en_GB.workaround.it where it is not known

In case you cannot carry out the commands above, then read on to perform the manual steps:

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 code 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.

  1. 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

  2. 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

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

  4. notToBeNull with empty assertionCreator lambda
    Search: notToBeNull\s*\{\s*\}
    Replace: notToBe null

  5. 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
  6. 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

  7. Switch from AssertImpl to ExpectImpl

    Search: AssertImpl
    Replace: ExpectImpl

  8. 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<

  9. Switch the API

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

  10. isLessOr/isGreaterOrEquals

    Search: is(Less|Greater)OrEquals
    Replace: is$1ThanOrEqual

11 use asList instead of asIterable and replace asEntries()

Search: \.asIterable\(\)
Replace: asList o

Search: asIterable(\s*\{)
Replace: asList$1

Search: asEntries\(\)
Replace: asEntries o

12 List get Index assertIt
This one has to be done with care as there could be nested assertion group blocks

Search: get\s*Index\(([^\)]+)\)\s*assertIt\s*\{([^\}]+)\}
Replace: get index($1) {$2}

Search: import ch.tutteli.atrium.api.infix.en_GB.Index
Replace: import ch.tutteli.atrium.api.infix.en_GB.index

13 Map getExisting Key assertIt
This one has to be done with care as there could be nested assertion group blocks

Search: getExisting\s*Key\(([^\)]+)\)\s*assertIt\s*\{([^\}]+)\}
Replace: getExisting key($1) {$2}

Search: import ch.tutteli.atrium.api.infix.en_GB.Key
Replace: import ch.tutteli.atrium.api.infix.en_GB.key

14 use it instead of o inside assertion groups:
Search: o
Replace: it (you can also replace by its)

15a. use new feature mechanism - replacements for Kotlin 1.4 or the new inference (skip to 13b in case you use Kotlin < 1.4)

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

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

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

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

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)
Replace: $1its feature of($2::$3)$4

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)
Replace: $1 its feature($2::$3)

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)
Replace: $1its feature of($2::$3)

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)
Replace: $1its feature of("$2.$3") { $2.$3 }

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

15b use new feature mechanism - replacements for Kotlin < 1.4 (skip if you already applied 11a)

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\((?:[\n\r\s]*)subject::([^\)]+)\)(\s*\{)
add import ch.tutteli.atrium.api.infix.en_GB.workaround.it to those files

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

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

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

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)(\s*\{)
Replace: $1its feature of($2::$3)$4

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\),]+)\)
Replace: $1 its feature($2::$3)

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([A-Z][^:]+)::([^\)]+)\)
Replace: $1its feature of($2::$3)

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

Search: ((?:[\n\r]+|\{)\s*)(?:property|returnValueOf|rueckgabewertVon)\(([^:]+)::([^\)]+)\)
Replace: $1its feature of("$2.$3") { $2.$3 }

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

But you still need to add manually import ch.tutteli.atrium.api.infix.en_GB.workaround.it where it is not known

16 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

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

  2. 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)
atrium - fix reporting issue when using Spek JVM

Published by robstoll over 4 years ago

See #485 for more details. All other features introduce in v0.11.0 are shown in release notes of v0.11.0

atrium - additional shortcuts for elementsOf

Published by robstoll over 4 years ago

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 and experimental features. But we want to progress as well and deprecate functionality in each version (e.g quite a lot with 0.7.0 and with 0.9.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 fluent-en_GB

  • #131 shortcut Iterable.containsExactlyElementsOf => thanks to @tkech17
  • #425 shortcut Iterable.containsElementsOf => thanks to @tkech17
  • #422 add elementsOf to contains.ignoreCase => thanks to @Miftahunajat

Domain / Core

  • none this time

Fixes

  • none this time

Improvements

  • #339 Avoid Duplicated Messages
  • #116 Migrate Spek1 specs to Spek2 => thanks to @assaflei
  • #416 move non-jvm specific specs to common => thanks to @assaflei

Breaking Changes

Planned (previously deprecated or announced)

  • none this time

Unplanned

  • none this time

Deprecation

  • none this time

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

There aren't any deprecations in this version and thus also no migration required if you update from 0.9.x or 0.10.0.

In case you migrate from 0.8.0 to this version, have a look at the migration guide given in the release notes of v0.9.0

atrium - shortcuts for Throwable.cause and Path.resolve

Published by robstoll over 4 years ago

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 and experimental features. 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 fluent-en_GB

  • #31 shortcut for Throwable.cause => thanks to @tfesenko for the implementation

jdk8 extensions

  • #216 shortcut for Path.resolve => thanks to @slalu for the implementation

Domain / Core

  • none this time

Fixes

  • none this time

Improvements

Breaking Changes

Planned (previously deprecated or announced)

  • none this time

Unplanned

  • none this time

Deprecation

  • none this time

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

Migrating deprecated functionality

There aren't any deprecations in this version and thus also no migration required if you update from 0.9.0.

In case you migrate from 0.8.0 to this version, have a look at the migration guide given in the release notes of v0.9.0

atrium - withOptions and withRepresentation as experimental feature

Published by robstoll over 4 years ago

Fixes

it was planned that withOptions ships with 0.9.0 (see #153). However, this was done only for the assertion verb which is used internally in Atrium but was not revealed for the predefined assertion verbs, hence this patch-version (thanks to @matejdro for the report - #362)

Most users won't use withOptions and thus we are going to present only withRepresentation for now (introduced in 0.9.2 #365).
❗❗Note though that withOptions and withRepresentation are both experimental and might be changed in a future version without previous notice nor migration path.

withRepresentation can be used as follows :

expect(listOf(1,2,2,3 /* imagine a lot more numbers */))
  .withRepresentation("xy numbers")
  .all { isLessThan(10) }

The error report looks then as follows in case of a failure:

expected that subject: xy numbers
◆ all entries: 
    » is less than: 10        (kotlin.Int <1234789>)
    ❗❗ following entries were mismatched: 
       ⚬ index 101: 12        (kotlin.Int <8933389>)
       ⚬ index 223: 10        (kotlin.Int <4523459>)

To use it, you have to add the following annotation to your test method/class @UseExperimental(ExperimentalWithOptions::class)

Further Improvements

  • #81 create sample MPP project => thanks to @bsemexan for most of the work

all other features as well a migration guide is given in the release notes of v0.9.0

atrium - fix for gradle 6 jdk8 issues

Published by robstoll over 4 years ago

all other features as well a migration guide is given in the release notes of v0.9.0

atrium - Expect as replacement for Assert and jdk8/kotlin 1.3 specific assertions

Published by robstoll over 4 years ago

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 and experimental features. 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

new API fluent-en_GB

  • #26 Introduced Expect<T> as replacement for Assert<out T> => things like expect(1).toBe("not an int") result now in a compile error
  • #66 allow to pass single Char to starts(Not)With/ends(Not)With => thanks to @kssc0112 for the implementation
  • #128 Iterable.contains.inOrder.only.elementsOf => thanks to @npswedberg for the implementation
  • #129 Iterable.contains.inAnyOrder.elementsOf => thanks to @sanatik for the implementation
  • #127 Iterable.contains.inAnyOrder.only.elementsOf => thanks to @johnGachihi for the implementation
  • #158 Iterable.hasNext/hasNotNext => thanks to @sanatik for the implementation
  • #163 shortcut for Iterable.min() => thanks to @piyushmor for the implementation
  • #163 shortcut for Iterable.min() => thanks to @Megamiun for the implementation
  • #130 CharSequence.contains.elementsOf => thanks to @mattyway for the implementation
  • #165 CharSequence.matches => thanks to @mikemolenda for the implementation
  • #165 CharSequence.mismatches => thanks to @shardulsonar for the implementation
  • #183 Array.asList => thanks to @piraces for the implementaiton

jdk8 extensions

  • #108 Path.exists and Path.existsNot with excellent failure hints => big thanks to @jGleitz for the implementation
  • #111 shortcut for Paht.isDirectory and Paht.isRegularFile => thanks to @jGleitz for the implementation
  • #112 shortcut for Paht.isReadable and Paht.isWritable => thanks to @jGleitz for the implementation
  • #187 Path.startsWith => thanks to @arjank for the implementation
  • #189 Path.startsNotWith => thanks to @arjank for the implementation
  • #188 Path.endsWith => thanks to @gaconkzk for the implementation
  • #190 Path.endsNotWith => thanks to @segunfamisa for the implementation
  • #109 shortcut for Path.fileName => thanks to @Tregz for the implementation
  • #110 shortcut for Path.getParent => thanks to @lpicanco for the implementation
  • #169 shortcut for Path.extension => thanks to @lelloman for the implementation
  • #170 shortcut for Path.fileNameWithoutExtension => thanks to @aljacinto for the implementation
  • #166 File.asPath => thanks to @lelloman for the implementation
  • #261 LocalDate(Time) and ZonedDatetime.isBefore => thanks to @sandjelkovic for the start and @name213 for the finishing
  • #261 LocalDate(Time) and ZonedDatetime.isBeforeOrEqual => thanks to @name213 for the implementation
  • #175 LocalDate(Time) and ZonedDatetime.isAfter => thanks to @name213 for the implementation
  • #262 LocalDate(Time) and ZonedDatetime.isAfterOrEqual => thanks to @lukebiddell for the implementation
  • #290 LocalDate(Time) and ZonedDatetime.isEqual => thanks to @name213 for the implementation
  • #174 shortcut for LocalDate(Time) and ZonedDatetime.year => thanks to @lpicanco for the implementation
  • #175 shortcut for LocalDate(Time) and ZonedDatetime.month => thanks to @ShradhaSangtani for the implementation
  • #176 shortcut for LocalDate(Time) and ZonedDatetime.day => thanks to @ShradhaSangtani for the implementation
  • #175 shortcut for LocalDate(Time) and ZonedDatetime.dayOfWeek => thanks to @sanatik for the implementation
  • #47 Optional.isEmpty => thanks to @arjank for the implementation
  • #113 shortcut for Optional.get named isPresent => thanks to @slalu for the implementation

kotlin 1.3 extensions

  • #203 Result.isSuccess => thanks to @shardulsonar
  • #204 Result.isFailure => thanks to @johnGachihi

Domain / Core

Features for assertion-function-writers:

  • introduced ExtractedFeaturePostStep and ChangedSubjectPostStep in order to have only one function on the domain level which covers both, narrowing features and features which expect an assertionCreator-lambda
  • ExpectImpl.feature.extractor
  • ExpectImpl.builder.representationOnly => assertion without description but only a representation

Others

  • #80 sample project for Atrium + junit5 => thanks to @bsemexan for the implementation
  • #207 sample project for Atrium + jasmine => thanks to @bsemexan for the implementation

Fixes

  • #143 domain-api-js was not included in bundle => thanks go to Darren Bell for reporting the issue

Improvements

  • #160 CharSequence.containsRegex accepts now also a Regex => thanks to @neelkamath for the implementation
  • #85 switch to implement instead of compile in build.gradle where possible => thanks to @kssc0112 for the implementation
    due to this cc-en_GB should no longer show up in cc-infix-en_GB
  • #193 update to spek 2.0.8 and use Spek's include => thanks to @Anubhav007 for the implementation
  • #202 use spek-js instead of dummy impl => thanks to @wudmer for the implementation
  • #239 spec for elementsOf empty iterable => thanks to @Megamiun for the implementation
  • #218 update tutteli-spek-extensions to 1.0.1 => thanks to @ShradhaSangtani for the implementation
  • #86 switch to native emoij => thanks to @Frandall
  • #156 improve specs for iterable, use one time consumable iterables => thanks to @aljacinto for the analysis and implementation
  • #296 git guide for newcomers as well as other fixes in CONTRIBUTING.md => thanks to @johnGachihi for the implementation
  • #285 do not report value type for map contains values
  • #297 rename ...OrEquals to ...OrEqual
  • #298 remove isA check in toBe for nullable types
  • #300 show only java's qualified name if different from kotlin => thanks to @Hubisco for the implementation
  • #303 workaround KT-35882, set cause of AtriumError explicit to null
  • #306 reword number of occurrences => thanks to @Jak-Sidious for the implementation
  • #307 change assertion verb in reporting => thanks to @Jak-Sidious for the implementation
  • #308 change toBe in reporting to equals => thanks to @Hubisco for the implementation

Breaking Changes

Planned (previously deprecated or announced)

  • none this time

Unplanned

  • none this time

Deprecation

The following was deprecated and will be removed with 1.0.0:

  • API cc-en_GB => use fluent-en_GB, infix-en_GB respectively
  • API cc-de_CH => there won't be a replacement, vote for #137 if you used it, we recommend you switch to fluent-en_GB
  • everything involving Assert/AssertionPlant and the like => switch to Expect and the like
  • Assert.subject, which means Expect.subject is deprecated as well. Subject is passed as argument to lambdas which have to deal with it.
    For instance, instead of writing createAndAddAssertion(TO_BE, expected) { subject == expected } one has to write createAndAddAssertion(TO_BE, expected) { it == expected }
  • ThrowableBuider including the assertion verb which dealt with exceptions (accepted a lambda) => can now be done with the regular expect function
  • SubjectProvider and AssertionHolder, both introduced in this version and it might well be we remove it with 1.0.0

The following deprecations are planned for a future version

  • this release does not yet include the new infix API. However, we are going to deprecate cc-infix-en_GB in favour of the new infix API infix-en_GB which is based on Expect as soon as the new infix API is ready.
  • AssertImpl will be deprecated in favour of ExpectImpl

Breaking Changes with 1.0.0

See atrium-roadmap -> Milestone 1.0.0

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 and 0.8.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 11 described below (don't forget the points 12, 13, ...), 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 ./ -path "*/test/*" -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/is(Less|Greater)OrEquals/is$1ThanOrEqual/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 code 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.

  1. 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

  2. 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

  3. 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

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

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

  6. 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
  7. 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

  8. Switch from AssertImpl to ExpectImpl

    Search: AssertImpl
    Replace: ExpectImpl

  9. 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<

  10. Switch the API

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

  11. isLessOr/isGreaterOrEquals

    Search: is(Less|Greater)OrEquals
    Replace: is$1ThanOrEqual

  12. 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

  1. Try to reduce duplicated 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

  2. 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)
atrium -

Published by robstoll almost 5 years ago

atrium -

Published by robstoll about 5 years ago