vitest icon indicating copy to clipboard operation
vitest copied to clipboard

console.log doens't work when there is an infinite loop after it.

Open searene opened this issue 3 years ago • 3 comments

Describe the bug

I noticed that console.log doesn't print anything when there's an infinite loop after it. Here is the test:

import { describe, it, expect} from 'vitest';

describe('add', () => {
  it ('1 + 1', () => {
    console.log("abc");
    while (true) {

    }
    expect(1 + 1).toBe(2);
  })
})

Here is the output after running yarn run vitest in the terminal

yarn run v1.22.18
$ /Users/joey/WebstormProjects/vitest-ext-basic-example/node_modules/.bin/vitest

 DEV  v0.12.10 /Users/joey/WebstormProjects/vitest-ext-basic-example

 · add.test.ts (1)

As you can see, abc isn't pointed out.

It should print something because sometimes we write infinite loop by accident, and we want to know where the error is. console.log gives a way to inspect the reason.

Reproduction

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

System Info

System:
    OS: macOS 12.4
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 563.12 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.2.0 - ~/.nvm/versions/node/v18.2.0/bin/node
    Yarn: 1.22.18 - /usr/local/bin/yarn
    npm: 8.9.0 - ~/.nvm/versions/node/v18.2.0/bin/npm
  Browsers:
    Chrome: 101.0.4951.64
    Safari: 15.5
  npmPackages:
    vite: ^2.9.9 => 2.9.9 
    vitest: ^0.12.6 => 0.12.10

Used Package Manager

yarn

Validations

searene avatar May 31 '22 13:05 searene

Yes, this is because logging is delegated to the main process on the last tick of the event loop, but infinite loop prevents us from reaching it.

sheremet-va avatar May 31 '22 13:05 sheremet-va

Yes, this is because logging is delegated to the main process on the last tick of the event loop, but infinite loop prevents us from reaching it.

is there any way to disable this process when debugging ?

ilovedesert001 avatar Jul 01 '22 02:07 ilovedesert001

is there any way to disable this process when debugging ?

No

sheremet-va avatar Sep 21 '22 05:09 sheremet-va

Even if the logging output isn't available, it seems like the infinite looping should be constrained by the timeout value. So the expected behavior would be that the loop runs for as long as the timeout value allows and then fails. Does this make sense? Would this be something easier to implement?

emersonthis avatar Nov 08 '22 19:11 emersonthis

is there any way to disable this process when debugging ?

We can probably add an option to not intercept console.log here:

https://github.com/vitest-dev/vitest/blob/393bf60cde7df1aaeff73486eea58edb1663dd6a/packages/vitest/src/runtime/setup.node.ts#L51

sheremet-va avatar May 30 '23 17:05 sheremet-va

is there any way to disable this process when debugging ?

I think you can patch globalThis.console back to direct stdout writing like this:

https://stackblitz.com/edit/vitest-dev-vitest-aff1ys?file=repro.test.ts

import { it, beforeAll } from 'vitest';

beforeAll(async () => {
  const { Console } = await import("node:console");
  globalThis.console = new Console(process.stdout, process.stderr);
});

it ('repro', () => {
  console.log("@@ before-loop");
  let i = 0;
  while (true) {
    console.log("@@ inside-loop", i++);
  }
})

One caveat is that --pool=threads seems to have a problem with flushing output in obvious infinite-loop like above, so it can print only "before-loop" part of logs. I tested with --pool=forks and it can print "inside-loop" logs.

(On stackblitz, the terminal gets stuck sometimes, so I also tested locally on my PC and the behavior regarding --pool seems to be same).

hi-ogawa avatar Dec 16 '23 03:12 hi-ogawa