Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"following elements were mismatched" hides the reason for the failure #1359

Open
vlsi opened this issue Mar 17, 2023 · 4 comments
Open

"following elements were mismatched" hides the reason for the failure #1359

vlsi opened this issue Mar 17, 2023 · 4 comments

Comments

@vlsi
Copy link
Collaborator

vlsi commented Mar 17, 2023

Affected Version

0.18.0

API

fluent-en_GB

Platform

jvm

Kotlin Version

1.8

How to reproduce the problem?

data class User(val login: String, val password: String)

expect(listOf(User("joe", "qwerty"), User("q", "qwerty1"))) {
    toHaveElementsAndAll {
        feature("login", { login })
            .feature("length", { length })
            .because("login should be longer than one letter") {
                toBeGreaterThan(1)
            }
        feature("password", { password })
            .because("password should be secure") {
                notToEqual("qwerty")
            }
    }
}

=>

I expected subject: [User(login=joe, password=qwerty), User(login=q, password=qwerty1)]        (java.util.Arrays.ArrayList <1453882535>)
◆ elements need all: 
    » ▶ login: 
        ◾ ▶ length: 
            ◾ to be greater than: 1        (kotlin.Int <2086658927>)
            ℹ because: login should be longer than one letter
    » ▶ password: 
        ◾ not to equal: "qwerty"        <151959367>
        ℹ because: password should be secure
    ❗❗ following elements were mismatched: 
       ⚬ index 0: User(login=joe, password=qwerty)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <1649737945>)
       ⚬ index 1: User(login=q, password=qwerty1)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <1943864595>)

Describe the bug

The output prints mismatched records, however, it does not report which expectations failed.

I see how printing all (failed or not) expectations for every element might produce a lot of output, so I would suggest that "following elements were mismatched" should hide the first level of successful expectations.

The following would be better:

I expected subject: [User(login=joe, password=qwerty), User(login=q, password=qwerty1)]        (java.util.Arrays.ArrayList <1453882535>)
◆ elements need all: 
    » ▶ login: 
        ◾ ▶ length: 
            ◾ to be greater than: 1        (kotlin.Int <2086658927>)
            ℹ because: login should be longer than one letter
    » ▶ password: 
        ◾ not to equal: "qwerty"        <151959367>
        ℹ because: password should be secure
    ❗❗ following elements were mismatched: 
       ⚬ index 0: User(login=joe, password=qwerty)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <1649737945>)
         ◾ ▶ password: "qwerty"        <536441346>
           ◾ not to equal: "qwerty"        <536441346>
           ℹ because: password should be secure
       ⚬ index 1: User(login=q, password=qwerty1)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <1943864595>)
         ◾ ▶ login: "q"        <1451530758>
             ◾ ▶ size: 1        (kotlin.Int <149368048>)
                 ◾ to be greater than: 1        (kotlin.Int <149368048>)
                 ℹ because: login should be longer than one letter

Expected behaviour

I would expect to see which expectations failed for every entry that fails.

If I rewrite the same test with at for loop, then it produces better reports:

expect(Unit) {
    for (user in listOf(User("joe", "qwerty"), User("q", "qwerty1"))) {
        feature("user", { user }) {
            feature("login", { login })
                .feature("size", { length })
                .because("login should be longer than one letter") {
                    toBeGreaterThan(1)
                }
            feature("password", { password })
                .because("password should be secure") {
                    notToEqual("qwerty")
                }
        }
    }
}

=>

I expected subject: kotlin.Unit        (kotlin.Unit <1938754399>)
◆ ▶ user: User(login=joe, password=qwerty)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <31225970>)
    ◾ ▶ password: "qwerty"        <536441346>
        ◾ not to equal: "qwerty"        <536441346>
        ℹ because: password should be secure
◆ ▶ user: User(login=q, password=qwerty1)        (ch.tutteli.atrium.api.fluent.en_GB.samples.ThrowableFeatureExtractorSamples$messageFeature2$User <1574610705>)
    ◾ ▶ login: "q"        <1451530758>
        ◾ ▶ size: 1        (kotlin.Int <149368048>)
            ◾ to be greater than: 1        (kotlin.Int <149368048>)
            ℹ because: login should be longer than one letter
@robstoll
Copy link
Owner

As mentioned in the duplicated issue #1360 this closely relates to #724 and I think we should also provide a report option which allows to define if we show also successful expectations or not.
I would also add an option which allows to hide/show because in the mismatch where I would not show them per default.
WDYT?

@vlsi
Copy link
Collaborator Author

vlsi commented Mar 17, 2023

we should also provide a report option which allows to define if we show also successful expectations or not

I guess that is yet another issue, and I think it would be worth having per-assertionCreator option to show expectations that hold.

@vlsi
Copy link
Collaborator Author

vlsi commented Mar 17, 2023

Yet another thing for allWithMismatchClauseAndDecorator would be to hide the top createExplanatoryAssertionGroup in case the list contains exactly one element.

When the actual list has one element only, then there's no much sense in printing "were require all the following assertions", and "by the way, here's an element that failed some of them" separately.

@robstoll
Copy link
Owner

robstoll commented Mar 17, 2023

I think it would be worth having per-assertionCreator option to show expectations that hold.

that's covered in #1342

When the actual list has one element only, then there's no much sense in printing "were require all the following assertions", and "by the way, here's an element that failed some of them" separately.

I agree, not sure yet how we want to show it in reporting though. I would still like to show that one used toHaveElementsAndAll and not toContainExactly. I see this as an additional improvement which has a lower priority IMO. Would you mind to create a separate issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants