Skip to content

toContain/toMatch assertion error doesn't show full string #5266

@hi-ogawa

Description

@hi-ogawa

Describe the bug

Currently toContain/toMatch is delegated to chai's builtin contain/include/match assertion and they don't enable showDiff:

return this.contain(item)

https://github.com/chaijs/chai/blob/61159d1a808af63ca64d9c57d582a624ab5761d9/lib/chai/core/assertions.js#L609-L614

Due to this, the error message from toContain/toMatch doesn't show full string while other assertions like toEqual do. To extend the truncated output in AssertionError: ..., users need to tweak chaiConfig.truncateThreshold https://vitest.dev/config/#chaiconfig-truncatethreshold and it feels like a minor papercut.

I think we can cover at least simple cases like expect(string).toMatch(string) on our own and use this.assert to enable showDiff and let pretty-format shows the diff (which I think currently doesn't handle do truncation though).

const s = `\
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
`;

test('toContain', () => {
  expect(s).toContain('hello');
});

test('toMatch', () => {
  expect(s).toMatch(/hello/);
});

test('toEqual', () => {
  expect(s).toEqual('hello'); // this diff shows full string
});
Vitest Output
npx vitest run

 RUN  v1.3.1 /home/projects/vitest-dev-vitest-argx1k

 ❯ test/basic.test.ts (3)
   × toContain
   × toMatch
   × toEqual

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  test/basic.test.ts > toContain
AssertionError: expected 'Lorem ipsum dolor sit amet, consectet…' to include 'hello'
 ❯ eval test/basic.test.ts:8:13
      6| 
      7| test('toContain', () => {
      8|   expect(s).toContain('hello');
       |             ^
      9| });
     10| 

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/3]⎯

 FAIL  test/basic.test.ts > toMatch
AssertionError: expected 'Lorem ipsum dolor sit amet, consectet…' to match /hello/
 ❯ eval test/basic.test.ts:12:13
     10| 
     11| test('toMatch', () => {
     12|   expect(s).toMatch(/hello/);
       |             ^
     13| });
     14| 

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/3]⎯

 FAIL  test/basic.test.ts > toEqual
AssertionError: expected 'Lorem ipsum dolor sit amet, consectet…' to deeply equal 'hello'

- Expected
+ Received

- hello
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit,
+ sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+

 ❯ eval test/basic.test.ts:16:13
     14| 
     15| test('toEqual', () => {
     16|   expect(s).toEqual('hello');
       |             ^
     17| });
     18| 

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/3]⎯

 Test Files  1 failed (1)
      Tests  3 failed (3)
   Start at  11:11:01
   Duration  2.23s (transform 56ms, setup 0ms, collect 25ms, tests 8ms, environment 0ms, prepare 201ms)
Also Jest output for comparison
npx jest
 FAIL  test/basic.test.ts
  ✕ toContain (2 ms)
  ✕ toMatch (1 ms)
  ✕ toEqual (3 ms)

  ● toContain

    Expected value   undefined
    Received:
      undefined
    
    Message:
      expect(received).toContain(expected) // indexOf
    
    Expected substring: "hello"
    Received string:    "Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    "

    Difference:

    Compared values have no visual difference.Error:

       6 |
       7 | test('toContain', () => {
    >  8 |   expect(s).toContain('hello');
         |             ^
       9 | });
      10 |
      11 | test('toMatch', () => {

      at Object.toContain (test/basic.test.ts:8:13)

  ● toMatch

    Expected value   undefined
    Received:
      undefined
    
    Message:
      expect(received).toMatch(expected)
    
    Expected pattern: /hello/
    Received string:  "Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    "

    Difference:

    Compared values have no visual difference.Error:

      10 |
      11 | test('toMatch', () => {
    > 12 |   expect(s).toMatch(/hello/);
         |             ^
      13 | });
      14 |
      15 | test('toEqual', () => {

      at Object.toMatch (test/basic.test.ts:12:13)

  ● toEqual

    Expected value   undefined
    Received:
      undefined
    
    Message:
      expect(received).toEqual(expected) // deep equality
    
    - Expected  - 1
    + Received  + 4
    
    - hello
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit,
    + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    +

    Difference:

    Compared values have no visual difference.Error:

      14 |
      15 | test('toEqual', () => {
    > 16 |   expect(s).toEqual('hello');
         |             ^
      17 | });
      18 |

      at Object.toEqual (test/basic.test.ts:16:13)

Test Suites: 1 failed, 1 total
Tests:       3 failed, 3 total
Snapshots:   0 total
Time:        0.397 s, estimated 1 s

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-argx1k?file=test%2Fbasic.test.ts

System Info

(stackblitz)

  System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.14.0 - /usr/local/bin/pnpm
  npmPackages:
    @vitest/ui: latest => 1.3.1 
    vite: latest => 5.1.4 
    vitest: latest => 1.3.1

Used Package Manager

npm

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions