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

assertEquals fails to throw on unequal instances of built-ins such as Temporal APIs (with --unstable-temporal flag) or URLSearchParams #6151

Closed
lionel-rowe opened this issue Oct 28, 2024 · 4 comments · Fixed by #6153
Labels
bug Something isn't working

Comments

@lionel-rowe
Copy link
Contributor

lionel-rowe commented Oct 28, 2024

Describe the bug

assertEquals fails when comparing various Temporal instances with polyfill or --unstable-temporal flag. It also similarly fails to compare other built-ins, such as URLPattern and URLSearchParams.

Steps to Reproduce

deno repl --unstable-temporal
import { assert, assertEquals, assertThrows } from 'jsr:@std/[email protected]'

// doesn't throw
assertEquals(
    Temporal.PlainDate.from('1999-09-09'),
    Temporal.PlainDate.from('1212-12-12'),
)

// throws in Deno (see https://github.com/denoland/std/issues/6151#issuecomment-2440809083); doesn't throw in browser
assertEquals(
    new URLSearchParams('?a=1&b=2'),
    new URLSearchParams('?a=1&b=99999'),
)

Equivalent results can be observed with unequal instances of Temporal.Instant, Temporal.ZonedDateTime, URLPattern, etc.

Expected behavior

assertEquals to throw when the instances are not value-equal.

Environment

OS: Ubuntu 20.04, WSL on Windows 11
deno version: 2.0.3
std version: [email protected]

@lionel-rowe lionel-rowe added bug Something isn't working needs triage labels Oct 28, 2024
@lionel-rowe
Copy link
Contributor Author

It looks like it's because objects are compared using own-properties, but all the properties of Temporal instances are defined on the prototype instead. I suspect this also means similar bugs exist for many other built-in and user-defined classes.

Possible means of patching for Temporal could include comparing toString or valueOf; a more generic fix could include comparing non-own properties up the prototype chain (not sure about perf implications though).

@kt3k
Copy link
Member

kt3k commented Oct 28, 2024

Possible means of patching for Temporal could include comparing toString or valueOf;

Adding special path for builtin Temporal makes sense to me (We already have special handling for Date). I don't think we need to do special things about polyfills.

@kt3k kt3k removed the needs triage label Oct 28, 2024
@lionel-rowe
Copy link
Contributor Author

lionel-rowe commented Oct 28, 2024

Adding special path for builtin Temporal makes sense to me (We already have special handling for Date). I don't think we need to do special things about polyfills.

I agree that there should be no special handling for polyfills, but also any solution for built-in Temporal should work seamlessly for any correctly implemented polyfill. I only mentioned that the issue also affects the polyfill to rule out the possibility it could be a bug in the V8 harmony Temporal implementation.

I'm not sure to what extent special-casing Temporal really makes sense, except maybe implementing a fast path if that noticeably improves perf. Notably, URL and RegExp are similarly special-cased as well as Date, but other built-ins that library consumers might reasonably want to compare, such as URLSearchParams and URLPattern, are not.

Upon further testing, URLSearchParams and URLPattern also fail to throw when unequal do work correctly within Deno, but it seems that's only thanks to Deno's non-standard addition of own-property symbols to instances of those objects (e.g. URLPattern having a Symbol("components") property). So such comparisons work correctly within Deno, but fail in the browser. I'm not sure what the rationale was for adding those symbol properties in the first place, but it might be worth revisiting their use (e.g. switching to WeakMaps) given that it introduces inconsistency between Deno and browsers. Looks like there's an issue for this already: denoland/deno#11720

@lionel-rowe lionel-rowe changed the title assertEquals fails when comparing various Temporal instances with polyfill or --unstable-temporal flag assertEquals fails to throw on unequal instances of built-ins such as Temporal APIs (with --unstable-temporal flag) or URLSearchParams Oct 28, 2024
@kt3k
Copy link
Member

kt3k commented Nov 6, 2024

Upon further testing, URLSearchParams and URLPattern also fail to throw when unequal do work correctly within Deno, but it seems that's only thanks to Deno's non-standard addition of own-property symbols to instances of those objects (e.g. URLPattern having a Symbol("components") property). So such comparisons work correctly within Deno, but fail in the browser. I'm not sure what the rationale was for adding those symbol properties in the first place, but it might be worth revisiting their use (e.g. switching to WeakMaps) given that it introduces inconsistency between Deno and browsers. Looks like there's an issue for this already: denoland/deno#11720

Fair enough. Dependency to Deno's specific implementation doesn't sound great. #6153 makes sense to me.

@kt3k kt3k closed this as completed in #6153 Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants