Skip to content

Commit

Permalink
fix flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mellyeliu committed Dec 10, 2024
1 parent c882412 commit 458ac61
Showing 1 changed file with 139 additions and 70 deletions.
209 changes: 139 additions & 70 deletions packages/cli/__tests__/compile-stylex-folder-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,65 @@ import { compileDirectory } from '../src/transform';
import * as cacheModule from '../src/cache';
import { getDefaultCachePath } from '../src/cache';

import fs from 'fs';
const fs = require('fs').promises;
import { isDir, getRelativePath } from '../src/files';
import * as path from 'path';

const cp = require('child_process');

process.chdir('__tests__/__mocks__');

function clearTestDir(config: CliConfig) {
async function clearTestDir(config: CliConfig) {
for (const output of config.output) {
fs.rmSync(output, { recursive: true, force: true });
await fs.rm(output, { recursive: true, force: true });
}
}

function runCli(args: string, config: CliConfig, onClose: () => void) {
function runCli(
args: string,
config: CliConfig,
onClose: () => void | Promise<void>,
) {
const cmd = 'node ' + path.resolve('../../lib/index.js ') + args;
console.log(cmd);
const script = cp.exec(cmd);
script.addListener('error', (err) => {
clearTestDir(config);
throw err;
clearTestDir(config)
.then(() => {
throw err;
})
.catch((clearErr) => {
throw new Error(`Failed to clear test directory: ${clearErr.message}`);
});
});
script.stderr.on('data', (data) => {
process.kill(script.pid);
clearTestDir(config);
throw new Error('failed to start StyleX CLI', data);
clearTestDir(config)
.then(() => {
throw new Error('Failed to start StyleX CLI', data);
})
.catch((clearErr) => {
throw new Error(`Failed to clear test directory: ${clearErr.message}`);
});
});
script.addListener('close', () => {
Promise.resolve(onClose())
.then(() => {})
.catch((err) => {
throw new Error(`Error in onClose callback: ${err.message}`);
});
});
script.addListener('close', onClose);
}

const snapshot = './snapshot';

const cachePath = getDefaultCachePath();
describe('compiling __mocks__/source to __mocks__/src correctly such that it matches __mocks__/snapshot', () => {
afterAll(() => {
fs.rmSync(config.output, { recursive: true, force: true });
fs.rmSync(cachePath, { recursive: true, force: true });
afterAll(async () => {
await fs.rm(config.output, { recursive: true, force: true });
await fs.rm(cachePath, { recursive: true, force: true });
});
// need to resolve to absolute paths because the compileDirectory function is expecting them.

const config: TransformConfig = {
input: path.resolve('./source'),
output: path.resolve('./src'),
Expand All @@ -70,24 +90,31 @@ describe('compiling __mocks__/source to __mocks__/src correctly such that it mat
},
};

afterAll(() => fs.rmSync(config.output, { recursive: true, force: true }));
afterAll(async () => {
await fs.rm(config.output, { recursive: true, force: true });
});

test(config.input, () => {
expect(isDir(config.input)).toBe(true);
test(config.input, async () => {
expect(await isDir(config.input)).toBe(true);
});

test(config.output, async () => {
fs.mkdirSync(config.output, { recursive: true });
expect(isDir(config.output)).toBe(true);
await fs.mkdir(config.output, { recursive: true });
expect(await isDir(config.output)).toBe(true);
await compileDirectory(config);
const outputDir = fs.readdirSync(config.output, { recursive: true });
const outputDir = await fs.readdir(config.output);
for (const file of outputDir) {
const outputPath = path.join(config.output, file);
const snapshotPath = path.join(snapshot, file);
expect(fs.existsSync(snapshotPath)).toBe(true);
expect(
await fs
.access(snapshotPath)
.then(() => true)
.catch(() => false),
).toBe(true);
if (path.extname(outputPath) === '.js') {
const outputContent = fs.readFileSync(outputPath).toString();
const snapshotContent = fs.readFileSync(snapshotPath).toString();
const outputContent = await fs.readFile(outputPath, 'utf-8');
const snapshotContent = await fs.readFile(snapshotPath, 'utf-8');
expect(outputContent).toEqual(snapshotContent);
}
}
Expand All @@ -103,23 +130,29 @@ describe('cli works with -i and -o args', () => {
watch: false,
babelPresets: [],
};
afterAll(() => clearTestDir(config));
afterAll(async () => await clearTestDir(config));

test('script start', (done) => {
const onClose = () => {
const onClose = async () => {
for (const dir of config.output) {
const outputDir = fs.readdirSync(dir, { recursive: true });
const outputDir = await fs.readdir(dir);
for (const file of outputDir) {
const snapshotDir = path.resolve(path.join(snapshot, file));
expect(fs.existsSync(snapshotDir)).toBe(true);
expect(
await fs
.access(snapshotDir)
.then(() => true)
.catch(() => false),
).toBe(true);
const outputPath = path.join(dir, file);
if (path.extname(outputPath) === '.js') {
const outputContent = fs.readFileSync(outputPath).toString();
const snapshotContent = fs.readFileSync(snapshotDir).toString();
const outputContent = await fs.readFile(outputPath, 'utf-8');
const snapshotContent = await fs.readFile(snapshotDir, 'utf-8');
expect(outputContent).toEqual(snapshotContent);
}
}
}
clearTestDir(config);
await clearTestDir(config);
done();
};

Expand All @@ -132,16 +165,22 @@ describe('cli works with -i and -o args', () => {
input: [path.resolve(config.input[0])],
output: [path.resolve(config.output[0])],
};
const onClose = () => {
expect(fs.existsSync(config.output[0])).toBe(true);
const onClose = async () => {
expect(
await fs
.access(config.output[0])
.then(() => true)
.catch(() => false),
).toBe(true);
done();
};
clearTestDir(absConfig);
runCli(
`-i ${absConfig.input[0]} -o ${absConfig.output[0]}`,
absConfig,
onClose,
);
clearTestDir(absConfig).then(() => {
runCli(
`-i ${absConfig.input[0]} -o ${absConfig.output[0]}`,
absConfig,
onClose,
);
});
}, 10000);
});

Expand All @@ -154,31 +193,37 @@ describe('cli works with multiple inputs and outputs', () => {
watch: false,
babelPresets: [],
};
afterAll(() => clearTestDir(config));
afterAll(async () => await clearTestDir(config));

test('script compiles multiple directories', (done) => {
const onClose = () => {
const onClose = async () => {
let isSecondOutput = false;
for (const dir of config.output) {
if (dir.endsWith('src2')) {
isSecondOutput = true;
}
const outputDir = fs.readdirSync(dir, { recursive: true });
const outputDir = await fs.readdir(dir);
for (const file of outputDir) {
if (isSecondOutput) {
expect(file).not.toContain(config.styleXBundleName);
}
const outputPath = path.join(dir, file);
const snapshotDir = isSecondOutput ? snapshot + '2' : snapshot;
const snapshotPath = path.join(snapshotDir, file);
expect(fs.existsSync(snapshotPath)).toBe(true);
expect(
await fs
.access(snapshotPath)
.then(() => true)
.catch(() => false),
).toBe(true);
if (path.extname(outputPath) === '.js') {
const outputContent = fs.readFileSync(outputPath).toString();
const snapshotContent = fs.readFileSync(snapshotPath).toString();
const outputContent = await fs.readFile(outputPath, 'utf-8');
const snapshotContent = await fs.readFile(snapshotPath, 'utf-8');
expect(outputContent).toEqual(snapshotContent);
}
}
}
clearTestDir(config);
await clearTestDir(config);
done();
};
const input = config.input.join(' ');
Expand All @@ -194,7 +239,7 @@ describe('individual testing of util functions', () => {
output: './src',
cssBundleName: 'stylex_bundle.css',
};
test('file to relative css path', () => {
test('file to relative css path', async () => {
const mockFileName = './src/pages/home/page.js';
const relativePath = getRelativePath(
mockFileName,
Expand All @@ -221,7 +266,6 @@ describe('cache mechanism works as expected', () => {
copiedNodeModules: false,
},
};

beforeEach(() => {
writeSpy = jest.spyOn(cacheModule, 'writeCache');
});
Expand All @@ -230,25 +274,27 @@ describe('cache mechanism works as expected', () => {
writeSpy.mockRestore();
});

afterAll(() => {
fs.rmSync(config.output, { recursive: true, force: true });
fs.rmSync(cachePath, { recursive: true, force: true });
afterAll(async () => {
await fs.rm(config.output, { recursive: true, force: true });
await fs.rm(cachePath, { recursive: true, force: true });
});

test('first compilation populates the cache', async () => {
fs.mkdirSync(config.output, { recursive: true });
fs.mkdirSync(cachePath, { recursive: true });
await fs.mkdir(config.output, { recursive: true });
await fs.mkdir(cachePath, { recursive: true });
writeSpy = jest.spyOn(cacheModule, 'writeCache');

await compileDirectory(config);
expect(writeSpy).toHaveBeenCalledTimes(3);

const cacheFiles = fs.readdirSync(cachePath);
const cacheFiles = await fs.readdir(cachePath);
expect(cacheFiles.length).toEqual(3);

for (const cacheFile of cacheFiles) {
const cacheFilePath = path.join(cachePath, cacheFile);
const cacheContent = JSON.parse(fs.readFileSync(cacheFilePath, 'utf-8'));
const cacheContent = JSON.parse(
await fs.readFile(cacheFilePath, 'utf-8'),
);
expect(cacheContent).toHaveProperty('inputHash');
expect(cacheContent).toHaveProperty('outputHash');
expect(cacheContent).toHaveProperty('collectedCSS');
Expand All @@ -267,18 +313,21 @@ describe('cache mechanism works as expected', () => {
const mockFilePath = path.join(config.input, 'index.js');
const mockFileOutputPath = path.join(config.output, 'index.js');
const newContent = 'console.log("Updated content");';
const originalContent = fs.readFileSync(mockFilePath, 'utf-8');
const originalOutputContent = fs.readFileSync(mockFileOutputPath, 'utf-8');
const originalContent = await fs.readFile(mockFilePath, 'utf-8');
const originalOutputContent = await fs.readFile(
mockFileOutputPath,
'utf-8',
);

fs.appendFileSync(mockFilePath, newContent, 'utf-8');
await fs.appendFile(mockFilePath, newContent, 'utf-8');

await compileDirectory(config);

// Ensure index.js is rewritten due to cache invalidation
expect(writeSpy).toHaveBeenCalledTimes(1);

fs.writeFileSync(mockFilePath, originalContent, 'utf-8');
fs.writeFileSync(mockFileOutputPath, originalOutputContent, 'utf-8');
await fs.writeFile(mockFilePath, originalContent, 'utf-8');
await fs.writeFile(mockFileOutputPath, originalOutputContent, 'utf-8');

writeSpy.mockRestore();
});
Expand All @@ -304,16 +353,26 @@ describe('CLI works with a custom cache path', () => {
};
config.cachePath = customCachePath;

beforeEach(() => {
if (fs.existsSync(customCachePath)) {
fs.rmSync(customCachePath, { recursive: true, force: true });
beforeEach(async () => {
if (
await fs
.access(customCachePath)
.then(() => true)
.catch(() => false)
) {
await fs.rm(customCachePath, { recursive: true, force: true });
}
});

afterAll(() => {
fs.rmSync(config.output, { recursive: true, force: true });
if (fs.existsSync(customCachePath)) {
fs.rmSync(customCachePath, { recursive: true, force: true });
afterAll(async () => {
await fs.rm(config.output, { recursive: true, force: true });
if (
await fs
.access(customCachePath)
.then(() => true)
.catch(() => false)
) {
await fs.rm(customCachePath, { recursive: true, force: true });
}
});

Expand All @@ -327,14 +386,24 @@ describe('CLI works with a custom cache path', () => {
path.relative(config.input, customFilePath) + '.json',
);

expect(fs.existsSync(customCachePath)).toBe(true);
expect(fs.existsSync(cacheFilePath)).toBe(true);

const cacheData = JSON.parse(fs.readFileSync(cacheFilePath, 'utf-8'));
expect(
await fs
.access(customCachePath)
.then(() => true)
.catch(() => false),
).toBe(true);
expect(
await fs
.access(cacheFilePath)
.then(() => true)
.catch(() => false),
).toBe(true);

const cacheData = JSON.parse(await fs.readFile(cacheFilePath, 'utf-8'));
expect(cacheData).toHaveProperty('inputHash');
expect(cacheData).toHaveProperty('outputHash');
expect(cacheData).toHaveProperty('collectedCSS');

fs.rmSync(cacheFilePath, { recursive: true, force: true });
await fs.rm(cacheFilePath, { recursive: true, force: true });
});
});

0 comments on commit 458ac61

Please sign in to comment.