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:



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
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.
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
I guess we're running into this.
Apparently Intl does not use space (ASCII 32) but non-breaking space (ASCII 160).
Sheesh Intl!
@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

@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?
@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.
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.
I think the reason for Intl behavior is to prevent wrapping (for example, in a table cell)
1.234,56
CHF
how to present context information like this when [...] the failure is deeper in the data structure
Bunch of ideas:
^ marker pointing at the line above at the relevant column@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:

Most helpful comment
@jeysal @cawoodm What do you think about this quick and dirty prototype using ES2018 RegExp Unicode property escapes (in Node 8 with
--harmony_regexp_propertyflag 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: