Skip to content

test: better Average tests - #1168

Open
giard-alexandre wants to merge 1 commit into
reactivemarbles:mainfrom
giard-alexandre:tests/avg-tests
Open

test: better Average tests#1168
giard-alexandre wants to merge 1 commit into
reactivemarbles:mainfrom
giard-alexandre:tests/avg-tests

Conversation

@giard-alexandre

Copy link
Copy Markdown
Contributor

Fleshing out Avg operator tests as the next step in #1031

using var source = new TestSourceCache<Person, string>(person => person.Name);

using var subscription = source.Connect()
.Avg(person => person.Age, emptyValue: -1)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, maybe you've got more context on this, given that you've probably looked at the source more than I have, after this PR, but.... how the hell does this make sense. The emptyValue parameter is explicitly documented as being "The resulting average value when there is no data." Why would we not expect the operator to emit this value in this test?

Is it actually a defect that the operator doesn't emit here? If so, I'd say implement the test as we WANT it to be, and mark it with Skip = "Existing defect: ..." and a short description. That's what I've been doing for other operators, as I've reworked them.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as you're making new files, go ahead and set them up to match the proper organization scheme. I.E. AvgFixture instead of AverageFixture to match the actual operator name.

No, there isn't any documentation for what the "proper organization scheme" is, as it should just be obvious from looking at the codebase. Except the codebase is utterly inconsistent, at the moment, cause there's so much of it to get around to reviewing and reorganizing.

I suppose since #1031 is the effort to slowly reorganize and modernize the codebase, I should add some notes there.

}

[Fact]
public void NullableValuesAreCountedAsZero()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really a desirable behavior? I assume it's something that's explicitly coded into the current operator, yes? It strikes me as a bad idea to make null coalescing an opt-out behavior, as opposed to opt-in. Even moreso, CAN you opt out of it?

Might be worth a breaking change in the API to go ahead and make, while you're rewrite the operator anyway.

Thoughts?

}

[Fact]
public void InvalidateWhenResubscribesAndReevaluatesValues()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's actually some behavior of .Avg() being tested here, that isn't tested elsewhere, the test name should clarify that. And ideally, it should be exercised without the use of another unrelated operator.

Otherwise, this test doesn't belong here. It seems to me that what's being tested here is actually the behavior of .InvalidateWhen(), not any behavior in .Avg(). All InvalidateWhen() is doing internally is a .Switch() over the upstream. so it's just unsubscribing and re-subscribing to it. There should already be separate tests for those things (at least, for un-subscribing, subscribing is basically already covered by every test).

}

[Fact]
public void AggregateChangeSetOverload_PreservesAverageBehavior()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "proper" organization for different operator overloads with the name is to give each one its own fixture. Which you're already doing with .ForCache and .ForList. Just make some more sub-fixtures off of that, say, .ForCache.ForChangeSet and .ForCache.ForAggregateChangeSet. See Cache.ToObservableChangeSetFixture for example.

If you don't think it's worth duplicating all the testing behavior, since one of these two operators is just an alias for the other, I'd agree. You can either make a base fixture class that they both inherit, say, .ForCache.Base, or just put the test functionality on the "inner" of the two, and have superficial testing of the alias's behavior on the other, with notes on the first fixture saying that the other fixture contains all the real behavioral tests.

}

[Fact]
public void AlreadyCompletedSource_InitialAverageAndCompletionPropagate()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I've done on other fixtures is combine this with the regular "SourceCompletes" test, and parameterize it with the StreamCompletionStrategy enum. Have a look at Cache.FilterFixture.Base.SourceFails_ErrorPropagates and Cache.FilterFixture.Status.SourceCompletes_CompletionPropagates.

If the if statements to handle two different behaviors ends up too tedious and you want to keep them as separate tests, at least use the same terminology of Immediate and Asynchronous termination. I.E. SourceCompletesImmediately and SourceCompletesAsynchronously.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply applicable comments from .ForCache to this file as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You actually want to keep this file (with renaming, mentioned below), but leave it empty. Without an empty file sharing the name prefix of the other two, you don't get any file nesting within IDEs. It's a change I made a few weeks ago to have files be automatically nested, based on name.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants