-
-
Notifications
You must be signed in to change notification settings - Fork 929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor lib/__tests__/standalone-cache.test.js
#5311
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,23 @@ | ||
'use strict'; | ||
|
||
const hash = require('../utils/hash'); | ||
const path = require('path'); | ||
const standalone = require('../standalone'); | ||
const fixturesPath = path.join(__dirname, 'fixtures'); | ||
const fCache = require('file-entry-cache'); | ||
const path = require('path'); | ||
const { promises: fs, existsSync } = require('fs'); | ||
|
||
const hash = require('../utils/hash'); | ||
const replaceBackslashes = require('../testUtils/replaceBackslashes'); | ||
const { promises: fs, constants: fsConstants } = require('fs'); | ||
const standalone = require('../standalone'); | ||
|
||
const fileExists = (filePath) => | ||
fs.access(filePath, fsConstants.F_OK).then( | ||
() => true, | ||
() => false, | ||
); | ||
// NOTE: `fs.rm(file, { force: true })` will be available when we drop the support of older Node versions. | ||
// See <https://nodejs.org/api/fs.html#fs_fs_rm_path_options_callback> | ||
const removeFile = async (filePath) => { | ||
if (existsSync(filePath)) { | ||
await fs.unlink(filePath); | ||
} | ||
}; | ||
|
||
const cwd = process.cwd(); | ||
const fixturesPath = path.join(__dirname, 'fixtures'); | ||
const invalidFile = path.join(fixturesPath, 'empty-block.css'); | ||
const syntaxErrorFile = path.join(fixturesPath, 'syntax_error.css'); | ||
const validFile = path.join(fixturesPath, 'cache', 'valid.css'); | ||
|
@@ -36,134 +39,108 @@ function getConfig() { | |
describe('standalone cache', () => { | ||
const expectedCacheFilePath = path.join(cwd, '.stylelintcache'); | ||
|
||
beforeEach(() => { | ||
beforeEach(async () => { | ||
// Initial run to warm up the cache | ||
return standalone(getConfig()); | ||
await standalone(getConfig()); | ||
}); | ||
|
||
afterEach(() => { | ||
afterEach(async () => { | ||
// Clean up after each test case | ||
return Promise.all([ | ||
fs.unlink(expectedCacheFilePath).catch(() => { | ||
// fs.unlink() throws an error if file doesn't exist and it's ok. We just | ||
// want to make sure it's not there for next test. | ||
}), | ||
fs.unlink(newFileDest).catch(() => { | ||
// fs.unlink() throws an error if file doesn't exist and it's ok. We just | ||
// want to make sure it's not there for next test. | ||
}), | ||
]); | ||
await removeFile(expectedCacheFilePath); | ||
await removeFile(newFileDest); | ||
}); | ||
|
||
it('cache file is created at $CWD/.stylelintcache', () => { | ||
it('cache file is created at $CWD/.stylelintcache', async () => { | ||
// Ensure cache file exists | ||
return fileExists(expectedCacheFilePath).then((isFileExist) => { | ||
expect(Boolean(isFileExist)).toBe(true); | ||
expect(existsSync(expectedCacheFilePath)).toBe(true); | ||
|
||
const fileCache = fCache.createFromFile(expectedCacheFilePath); | ||
const { cache } = fileCache; | ||
const { cache } = fCache.createFromFile(expectedCacheFilePath); | ||
|
||
// Ensure cache file contains only linted css file | ||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
expect(typeof cache.getKey(newFileDest) === 'undefined').toBe(true); | ||
}); | ||
// Ensure cache file contains only linted css file | ||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [note] I've added the expectation |
||
expect(cache.getKey(newFileDest)).toBeUndefined(); | ||
}); | ||
|
||
it('only changed files are linted', () => { | ||
it('only changed files are linted', async () => { | ||
// Add "changed" file | ||
return fs | ||
.copyFile(validFile, newFileDest) | ||
.then(() => { | ||
// Next run should lint only changed files | ||
return standalone(getConfig()); | ||
}) | ||
.then((output) => { | ||
// Ensure only changed files are linted | ||
const isValidFileLinted = Boolean(output.results.find((file) => file.source === validFile)); | ||
const isNewFileLinted = Boolean(output.results.find((file) => file.source === newFileDest)); | ||
|
||
expect(isValidFileLinted).toBe(false); | ||
expect(isNewFileLinted).toBe(true); | ||
|
||
const fileCache = fCache.createFromFile(expectedCacheFilePath); | ||
const { cache } = fileCache; | ||
|
||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
expect(typeof cache.getKey(newFileDest) === 'object').toBe(true); | ||
}); | ||
await fs.copyFile(validFile, newFileDest); | ||
|
||
// Next run should lint only changed files | ||
const { results } = await standalone(getConfig()); | ||
|
||
// Ensure only changed files are linted | ||
expect(results.some((file) => file.source === validFile)).toBe(false); | ||
expect(results.some((file) => file.source === newFileDest)).toBe(true); | ||
|
||
const { cache } = fCache.createFromFile(expectedCacheFilePath); | ||
|
||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
expect(typeof cache.getKey(newFileDest)).toBe('object'); | ||
expect(cache.getKey(newFileDest)).toBeTruthy(); | ||
}); | ||
|
||
it('all files are linted on config change', () => { | ||
it('all files are linted on config change', async () => { | ||
const changedConfig = getConfig(); | ||
|
||
changedConfig.config.rules['block-no-empty'] = false; | ||
|
||
return fs | ||
.copyFile(validFile, newFileDest) | ||
.then(() => { | ||
// All file should be re-linted as config has changed | ||
return standalone(changedConfig); | ||
}) | ||
.then((output) => { | ||
// Ensure all files are re-linted | ||
const isValidFileLinted = Boolean(output.results.find((file) => file.source === validFile)); | ||
const isNewFileLinted = Boolean(output.results.find((file) => file.source === newFileDest)); | ||
|
||
expect(isValidFileLinted).toBe(true); | ||
expect(isNewFileLinted).toBe(true); | ||
}); | ||
await fs.copyFile(validFile, newFileDest); | ||
|
||
// All file should be re-linted as config has changed | ||
const { results } = await standalone(changedConfig); | ||
|
||
// Ensure all files are re-linted | ||
expect(results.some((file) => file.source === validFile)).toBe(true); | ||
expect(results.some((file) => file.source === newFileDest)).toBe(true); | ||
}); | ||
|
||
it('invalid files are not cached', () => { | ||
return fs | ||
.copyFile(invalidFile, newFileDest) | ||
.then(() => { | ||
// Should lint only changed files | ||
return standalone(getConfig()); | ||
}) | ||
.then((output) => { | ||
expect(output.errored).toBe(true); | ||
// Ensure only changed files are linted | ||
const isValidFileLinted = Boolean(output.results.find((file) => file.source === validFile)); | ||
const isInvalidFileLinted = Boolean( | ||
output.results.find((file) => file.source === newFileDest), | ||
); | ||
|
||
expect(isValidFileLinted).toBe(false); | ||
expect(isInvalidFileLinted).toBe(true); | ||
|
||
const fileCache = fCache.createFromFile(expectedCacheFilePath); | ||
const { cache } = fileCache; | ||
|
||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
expect(typeof cache.getKey(newFileDest) === 'undefined').toBe(true); | ||
}); | ||
it('invalid files are not cached', async () => { | ||
await fs.copyFile(invalidFile, newFileDest); | ||
|
||
// Should lint only changed files | ||
const { errored, results } = await standalone(getConfig()); | ||
|
||
expect(errored).toBe(true); | ||
|
||
// Ensure only changed files are linted | ||
expect(results.some((file) => file.source === validFile)).toBe(false); | ||
expect(results.some((file) => file.source === newFileDest)).toBe(true); | ||
|
||
const { cache } = fCache.createFromFile(expectedCacheFilePath); | ||
|
||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
expect(cache.getKey(newFileDest)).toBeUndefined(); | ||
}); | ||
it('files with syntax errors are not cached', () => { | ||
return fs | ||
.copyFile(syntaxErrorFile, newFileDest) | ||
.then(() => { | ||
// Should lint only changed files | ||
return standalone(getConfig()); | ||
}) | ||
.then(() => { | ||
const fileCache = fCache.createFromFile(expectedCacheFilePath); | ||
const { cache } = fileCache; | ||
|
||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
expect(typeof cache.getKey(newFileDest) === 'undefined').toBe(true); | ||
}); | ||
|
||
it('files with syntax errors are not cached', async () => { | ||
await fs.copyFile(syntaxErrorFile, newFileDest); | ||
|
||
// Should lint only changed files | ||
await standalone(getConfig()); | ||
|
||
const { cache } = fCache.createFromFile(expectedCacheFilePath); | ||
|
||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
expect(cache.getKey(newFileDest)).toBeUndefined(); | ||
}); | ||
|
||
it('cache file is removed when cache is disabled', async () => { | ||
const noCacheConfig = getConfig(); | ||
|
||
noCacheConfig.cache = false; | ||
|
||
await standalone(noCacheConfig); | ||
await expect(fileExists(expectedCacheFilePath)).resolves.toBe(false); | ||
expect(existsSync(expectedCacheFilePath)).toBe(false); | ||
}); | ||
// eslint-disable-next-line jest/no-disabled-tests | ||
it.skip("cache doesn't do anything if string is passed", async () => { | ||
|
||
it("cache doesn't do anything if string is passed", async () => { | ||
// Ensure no cache file | ||
await removeFile(expectedCacheFilePath); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [note] This addition of |
||
|
||
const config = { | ||
code: '.foo {}', | ||
codeFilename: 'foo.css', | ||
|
@@ -178,64 +155,50 @@ describe('standalone cache', () => { | |
const lintResults = await standalone(config); | ||
|
||
expect(lintResults.errored).toBe(false); | ||
|
||
await expect(fileExists(expectedCacheFilePath)).resolves.toBe(false); | ||
expect(existsSync(expectedCacheFilePath)).toBe(false); | ||
}); | ||
}); | ||
|
||
describe('standalone cache uses cacheLocation', () => { | ||
const cacheLocationFile = path.join(fixturesPath, 'cache', '.cachefile'); | ||
const cacheLocationDir = path.join(fixturesPath, 'cache'); | ||
const expectedCacheFilePath = path.join(cacheLocationDir, `.stylelintcache_${hash(cwd)}`); | ||
|
||
afterEach(() => { | ||
afterEach(async () => { | ||
// clean up after each test | ||
return Promise.all([ | ||
fs.unlink(expectedCacheFilePath).catch(() => { | ||
// fs.unlink() throws an error if file doesn't exist and it's ok. We just | ||
// want to make sure it's not there for next test. | ||
}), | ||
fs.unlink(cacheLocationFile).catch(() => { | ||
// fs.unlink() throws an error if file doesn't exist and it's ok. We just | ||
// want to make sure it's not there for next test. | ||
}), | ||
]); | ||
await removeFile(expectedCacheFilePath); | ||
await removeFile(cacheLocationFile); | ||
}); | ||
it('cacheLocation is a file', () => { | ||
|
||
it('cacheLocation is a file', async () => { | ||
const config = getConfig(); | ||
|
||
config.cacheLocation = cacheLocationFile; | ||
|
||
return standalone(config) | ||
.then(() => { | ||
// Ensure cache file is created | ||
return fileExists(cacheLocationFile); | ||
}) | ||
.then((fileStats) => { | ||
expect(Boolean(fileStats)).toBe(true); | ||
await standalone(config); | ||
|
||
// Ensure cache file is created | ||
expect(existsSync(cacheLocationFile)).toBe(true); | ||
|
||
const fileCache = fCache.createFromFile(cacheLocationFile); | ||
const { cache } = fileCache; | ||
const { cache } = fCache.createFromFile(cacheLocationFile); | ||
|
||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
}); | ||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
}); | ||
it('cacheLocation is a directory', () => { | ||
|
||
it('cacheLocation is a directory', async () => { | ||
const config = getConfig(); | ||
|
||
config.cacheLocation = cacheLocationDir; | ||
|
||
return standalone(config) | ||
.then(() => { | ||
return fileExists(expectedCacheFilePath); | ||
}) | ||
.then((cacheFileStats) => { | ||
// Ensure cache file is created | ||
expect(Boolean(cacheFileStats)).toBe(true); | ||
await standalone(config); | ||
|
||
// Ensure cache file is created | ||
expect(existsSync(expectedCacheFilePath)).toBe(true); | ||
|
||
const fileCache = fCache.createFromFile(expectedCacheFilePath); | ||
const { cache } = fileCache; | ||
const { cache } = fCache.createFromFile(expectedCacheFilePath); | ||
|
||
expect(typeof cache.getKey(validFile) === 'object').toBe(true); | ||
}); | ||
expect(typeof cache.getKey(validFile)).toBe('object'); | ||
expect(cache.getKey(validFile)).toBeTruthy(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[note] I think it simple and enough to use
fs.existsSync()
for tests.