Visitar URL original
fix(hottesting): a feed that reads a service is a required input, whatever else it reads by rajamatt · Pull Request #3287 · unoplatform/uno.extensions · GitHub
Skip to content

fix(hottesting): a feed that reads a service is a required input, whatever else it reads - #3287

Open
rajamatt wants to merge 6 commits into
mainfrom
dev/mara/mock-service-wins-over-feed
Open

rajamatt wants to merge 6 commits into
mainfrom
dev/mara/mock-service-wins-over-feed

Conversation

@rajamatt

@rajamatt rajamatt commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

GitHub Issue (If applicable): closes #3283

PR Type

  • Bugfix

What is the current behavior?

A feed that reads both a constructor service and another feed of the model is classified as derived, so it is optional in {Model}Mock and left out of Empty. Two common shapes are affected:

  • a search over a query state: Query.SelectAsync((query, ct) => Service.Search(query, ct));
  • a list with a selection: ListFeed.Async(...).Selection(SelectedTask).

Left unset, the member runs its real logic over the null-injected service. Create(), and any mock that does not set it, shows its error.

What is the new behavior?

  • A feed that reads a service is a required input, whatever else it reads. Empty covers it, and the compiler asks for it in every mock.
  • This matches spec 013 §7: the required members are exactly the service-dependent feeds. A derived member is optional because its real logic recomputes over the mocked inputs, and that cannot hold when the logic reads a service.
  • Both paths agree:
    • the shared classification ranks a parameter before a feed;
    • the MVUX generator emits both OnParameter and OnFeed for such a member;
    • the metadata path treats a member as derived only when every [FeedDependency] on it names a feed.
  • A service is a parameter of one of the model's constructors. A lambda parameter with the same name doesn't count.

Reviewer's guide

  • Start here: FeedDependencyAnalysis.ClassifyFeedMember, where the two checks swap order, then FeedsMockGenerator.ReadFeedDependencies.
  • Reverses a pinned rule: fix(hottesting): declare a mock member once when it has several dependencies #3193 pinned "a member declared both input and derived is derived" in When_MemberIsDeclaredBothInputAndDerived_Then_MockTreatsItAsDerivedLikeTheSourcePath. That test is renamed ..._Then_MockRequiresItLikeTheSourcePath and now asserts the opposite.
  • Tests that prove it: the first commit, 0a776dce0, adds tests only, and all of them fail on main.
    • Given_GeneratedMock.When_CreateDefault_Then_AFeedReadingAServiceAndAnotherFeedIsEmptyToo (fixture SearchModel): on main the list's first message carries the NullReferenceException from the real Search.
    • Given_GeneratedMock.When_FeedReadsAServiceAndAnotherFeed_Then_MockRequiresIt.
    • Given_FeedsMockGenerator: a search, a list with a selection, and the hand-declared mix above.
  • Review fix: 48780d9b9. A lambda parameter named like a constructor parameter made a derived feed required; When_DerivedFeedHasALambdaParameterNamedLikeACtorParameter_Then_ItStaysOptional failed before it. The same commit adds the OnFeed emission and the attribute remarks.
  • Docs commits: 4746e8fd3 and 664fa6563: testing.md and spec 013 (architecture, implementation, history v20).
  • Unrelated, one line: 02ff6a312 replaces a hard tab in spec 026 that came from main (fix(reactive): MVUX hot reload of a command's parameters crashes or loses list updates #3296), so the docs validation passes.

PR Checklist

  • Tested code with current supported SDKs: unit tests only (Uno.HotTesting.Reactive.Tests 44 pass; Uno.Extensions.Reactive.Tests 1655 pass, 19 skipped; Uno.Extensions.Core.Tests 61 pass). UI and runtime tests were not run locally.
  • Docs have been added/updated.
  • Unit Tests for the changes have been added: 6 new, 1 updated.
  • Contains NO breaking changes: see below.
  • Associated with an issue.

Breaking change: a mock that left such a member unset no longer compiles, because the member is now required. Setting it, or starting from {Model}Mock.Empty with { ... }, fixes the call site. Because the change is breaking, it should not be backported to release/stable/8.0.

Other information

🤖 Generated with Claude Code

rajamatt and others added 5 commits November 13, 2026 10:32
…ired input

- Fixture SearchModel: a search over a query state
- Generator cases: a search, a list with a selection, hand-declared OnParameter and OnFeed on one member
- Fails on main: such a member is optional and left out of Empty, so Create() runs its loader over the null service

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tever else it reads

- The shared classification ranks a constructor parameter before a feed, so the MVUX generator emits OnParameter for such a member and the source path makes it required
- The metadata path treats a member as derived only when every [FeedDependency] on it names a feed
- {Model}Mock.Empty and every mock now cover a search over a query state or a list with a selection

Closes #3283

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lse it reads

- testing.md: name the search and selection shapes among the required inputs
- Spec 013: classification rule (architecture §2.1, implementation §3), history v20

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… mixed members keep their feed links

- Classification counts a parameter as a service only when it belongs to one of the model's constructors: a lambda parameter of the same name made a derived feed required
- The MVUX generator emits OnFeed next to OnParameter for a member that reads both, so the metadata keeps every link; the reader already ranks the parameter first
- FeedDependencyAttribute: the OnFeed item says it holds only when no instance names a parameter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he selection swap

- history v20: both attributes emitted, lambda parameters excluded, the accepted simplification, the metadata path needs a rebuild; "spec §7"
- testing.md: name only the search shape until a list with a selection can be swapped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rajamatt
rajamatt force-pushed the dev/mara/mock-service-wins-over-feed branch from 270af99 to 664fa65 Compare November 13, 2026 15:36
- Line 33 of specs/026-mvux-hr-replaced-model-ctor-guard/spec.md starts with a tab, which fails markdownlint MD010
- The docs validation runs on pull requests that change doc/, so this fails them until main is fixed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mergify

mergify Bot commented Nov 13, 2026

Copy link
Copy Markdown

Tick the box to add this pull request to the merge queue (same as @mergifyio queue). If it does not match the queue conditions yet, it enters the queue once it does.

  • Queue this pull request

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.

A mocked view model still loads a list with a selection from its real service

1 participant