simonc / memfs

MemFs provides a fake file system that can be used for tests. Strongly inspired by FakeFS.
MIT License
320 stars 27 forks source link

Replace mockFs load method #47

Open dicolasi opened 2 months ago

dicolasi commented 2 months ago

Hi all, I am in the process of replacing mock-fs with mem-fs due to its lack of support for node 20.X. I am struggling to get mem-fs working in this simple case:

Here the original test case with mock-fs:

  it('should use local hosts if they exist', async () => {
    mockFs({
      'admin/exchange-hosts.yaml': mockFs.load('test/unit/input-files/exchange-hosts.yaml'),
      'exchange-config': mockFs.load('test/unit/input-files/gateway/exchange-config-integration')
    });
    await validateHostsByEnvironment({ exchangeConfigPath: 'exchange-config', env: Environment.production, validation });
    expect(validation.errors).to.be.empty;
    expect(validation.warnings).to.be.empty;
    expect(validation.info).to.contain('[prod/real.yaml] Hosts authorised');
    expect(getExchangeHostsRawStub.notCalled).to.be.true;
  });

and here the refactored one with mem-fs that does not work:

  it('should use local hosts if they exist', async () => {
    vol.fromNestedJSON({
      'admin/exchange-hosts.yaml': ufs.readFileSync('test/unit/input-files/exchange-hosts.yaml'),
      'exchange-config': await loadIntoMockFS('test/unit/input-files/gateway/exchange-config-integration'),
    }, appPath);
    await validateHostsByEnvironment({ exchangeConfigPath: 'exchange-config', env: Environment.production, validation });
    expect(validation.errors).to.be.empty;
    expect(validation.warnings).to.be.empty;
    expect(validation.info).to.contain('[prod/real.yaml] Hosts authorised');
    expect(getExchangeHostsRawStub.notCalled).to.be.true;
  });

the method loadIntoMockFS is here:

async function loadIntoMockFS(dirPath: string): Promise<NestedDirectoryJSON> {
  const entries = await fsPromises.readdir(dirPath, {withFileTypes: true});
  const fileTree: NestedDirectoryJSON = {};

  for (const entry of entries) {
    const entryPath = path.join(dirPath, entry.name);
    if (entry.isDirectory()) {
      fileTree[entry.name] = await loadIntoMockFS(entryPath);
    } else if (entry.isFile()) {
      fileTree[entry.name] = await fsPromises.readFile(entryPath, 'utf-8');
    }
  }

  return fileTree;
}

I am not sure I actually need the loadIntoMockFS method at all. The test fail since the folder exchange-config cannot be found (but if I print vol.tree I can definitely see it).

I am sure I am missing something stupid here :)

SukkaW commented 2 months ago

This is actually a nice feature to have! I am having the exactly same use case.

I can implement this feature in a PR if maintainers approve it.

dicolasi commented 2 months ago

@SukkaW that would be great!

simonc commented 2 months ago

Hi 🙂 I'd be happy to review and approve a PR. Just to be sure though. The code in the issue is in JS while memFS uses Ruby. Du you use memFS with JS?