1import { fs, vol } from 'memfs';
2
3import * as Log from '../../log';
4import { FileNotifier } from '../FileNotifier';
5
6jest.mock('../../log');
7
8const asMock = <T extends (...args: any[]) => any>(fn: T): jest.MockedFunction<T> =>
9  fn as jest.MockedFunction<T>;
10const originalCwd = process.cwd();
11
12beforeEach(() => {
13  vol.reset();
14});
15
16beforeAll(() => {
17  process.chdir('/');
18  // @ts-expect-error
19  fs.watchFile = jest.fn(fs.watchFile);
20});
21
22afterAll(() => {
23  process.chdir(originalCwd);
24});
25
26it('returns null when no files can be found', () => {
27  vol.fromJSON({}, '/');
28  const fileNotifier = new FileNotifier('./', ['babel.config.js']);
29  expect(fileNotifier.startObserving()).toBe(null);
30});
31
32it('observes the first existing file', () => {
33  asMock(Log.log).mockClear();
34  asMock(fs.watchFile)
35    .mockClear()
36    // @ts-expect-error
37    .mockImplementationOnce((_, callback) => {
38      // @ts-expect-error: polymorphism
39      callback({}, { size: 1 });
40    });
41
42  vol.fromJSON(
43    {
44      'babel.config.js': '',
45    },
46    '/'
47  );
48  const fileNotifier = new FileNotifier('./', [
49    // Skips this file
50    '.babelrc',
51    // Starts observing
52    'babel.config.js',
53  ]);
54  expect(fileNotifier.startObserving()).toBe('babel.config.js');
55
56  // We mock out the callback firing and test that a warning was logged.
57  expect(Log.log).toBeCalledTimes(1);
58  expect(Log.log).toBeCalledWith(expect.stringContaining('babel.config.js'));
59});
60