Closed antonsatin closed 4 months ago
Thank you for the report!
assigns
are maps and the order of map keys are not guaranteed. It will change based on many factors, it could even be different between mix test
executions.
Regardless of the maps behaviour, you should not assert on the generated content, because it leads to brittle tests. Even if order was preserved, <.link
could change this order between versions. It would be better to write your tests in a way that you fetch the element and then assert on specific attributes, such as:
content = view |> element("some selector") |> render()
assert content =~ ~s/data-foo="bar"/
Or use Floki alongside Floki.attributes to parse and access attributes in a order independent way. :)
Thank you for the swift reply @josevalim!
I agree that with maps it's expected, why I thought it's worth highlighting is because when using html-like syntax it's not obvious that the order may shift. Correct me if I'm wrong, but this concept is also exclusive to components so if we render HEEx with just HTML inside it won't change? So I wanted to clarify if this was an issue with internals or an expected behaviour.
Maybe there's something to add to documentation? Section about components that I linked specifically examples an exact string match when testing components. So perhaps the order nuance can be mentioned in HEEx docs and testings docs. What do you think? Maybe I missed something here :)
Yes, it is about components because components are just a function. What are you passing is options to a function and there is no guarantee the order may be respected. And, even if it wanted to respect the order, the choice of maps wouldn't help much either. :) Feel free to send a PR for docs if you think there is a particular place it could help. Perhaps some notes on how to assert on the generated results of LiveViewTest.
Environment
Actual behavior
Hi folks šš» There seems to be an inconsistent order of attributes when rendering components inside templates. It's somehow affected by the
--cover
flag when running tests. It may also be affected by other things - we discovered it as an intermittent error initially.@maciej-szlosarczyk isolated the issue to
--cover
flag and has an example repository with this issue as well as CI check that reproduces this issue.Given a component like this:
And a test like this:
When running the test with and without
--cover
flag rendered component will produce different results changing order ofclass
anddata-foo
attributes.I did some debugging and it seems that when assigns arrive to
Phoenix.LiveView.TagEngine.component/3
they are in different order.versus
That's as far as I could get - I'm not sure where assigns turn from list to a map.
Expected behavior
I would expect order to be consistent like it is between runs without
--cover
flag, especially since testing docs recommend exact match on strings when testing components.