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

String Comparison Incorrect #9239

Closed
cawoodm opened this issue Nov 28, 2019 · 9 comments
Closed

String Comparison Incorrect #9239

cawoodm opened this issue Nov 28, 2019 · 9 comments

Comments

@cawoodm
Copy link

cawoodm commented Nov 28, 2019

🐛 Bug Report

When comparing the string "1.234,56 CHF" to "1.234,56 CHF" (apparently identical) Jest is coming up with not equal. It boils down to JavaScript being weird in that "1.234,56 CHF" == String("1.234,56 CHF") is apparently false.

jasmineUtils.js:
image

image

image

envinfo

  System:
    OS: Windows 10 10.0.16299
    CPU: (4) x64 Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
  Binaries:
    Node: 13.2.0 - C:\prg\nodejs\node.EXE
    Yarn: 1.5.1 - C:\prg\yarn\bin\yarn.CMD
    npm: 6.13.1 - C:\prg\nodejs\npm.CMD
  npmPackages:
    jest: ^24.9.0 => 24.9.0
@jeysal
Copy link
Contributor

jeysal commented Nov 28, 2019

You'll need to supply a repro showing how you actually create the strings you are comparing.
'a' is equal to String('a') but not to new String('a'). If that's what you're seeing, it's intended behavior. Otherwise it's a bug that we'll need a repro for.

@jeysal jeysal closed this as completed Nov 28, 2019
@cawoodm
Copy link
Author

cawoodm commented Nov 29, 2019

You could try the following:

// Format a currency as a localized string
const formatter = new Intl.NumberFormat('de', {
    style: 'currency',
    currency: 'CHF
});
let o = {
    value: formatter.format(1234.56)
};

// Fail
expect(o).toHaveProperty('value', '1.234,56 CHF'); // Nope

// Workaround
expect(o.replace(/\s/, ' ')).toEqual('1.234,56 CHF'); // Yup

@cawoodm
Copy link
Author

cawoodm commented Nov 29, 2019

I guess we're running into this.

Apparently Intl does not use space (ASCII 32) but non-breaking space (ASCII 160).

Sheesh Intl!

@jeysal
Copy link
Contributor

jeysal commented Nov 29, 2019

@pedrottimark I think it's good that the character-by-character diff already highlights where the mismatch is here - any ideas/plans on how to improve on diffs invisible to humans in the future?
Prior art
image

@pedrottimark
Copy link
Contributor

@jeysal Thank you for adding a specific example to my mental slow cooker.

Because you have such a strong intuition about first impressions in developer experience, here is a question for your imagination: how to present context information like this when instead of toBe(string) or toEqual(string) the failure is deeper in the data structure, like an array item or object property?

@pedrottimark
Copy link
Contributor

@cawoodm Thank you for taking the time to report the issue and especially your discovery.

This is same issue as #6881 but your follow up comment is more specific about the reason.

  1. To close the loop, if you imagine test-driven development (even if that was not your methodology) you wrote the expected spec string with a space, and then the received failed because it has no-break space? This is a very helpful example as Tim commented for Jest to improve the information it reports, so you can decide whether it is problem with test code or tested code, or both.

  2. I think the reason for Intl behavior is to prevent wrapping (for example, in a table cell)

1.234,56
CHF

@jeysal
Copy link
Contributor

jeysal commented Dec 4, 2019

how to present context information like this when [...] the failure is deeper in the data structure

Bunch of ideas:

  • Just squeeze it into the line below with a ^ marker pointing at the line above at the relevant column
  • Line-comment style to the right in a different color (would have to be short)
  • Some sort of footnote indicator?

@pedrottimark
Copy link
Contributor

@jeysal @cawoodm What do you think about this quick and dirty prototype using ES2018 RegExp Unicode property escapes (in Node 8 with --harmony_regexp_property flag and in Node 10 without flag) to detect replacement of adjacent characters which have General_Category=Space_Separator and format the code point (if either or both are not space).

There are probably some more low-hanging fruit like delete or insert of zero-width characters.

Baseline at left and imagined relevant comparison at right:

2019-12-06 space separator

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants