File System
The file system plugin allows you to easily manage files and directories during tests and write assertions against them. You can install the plugin from the npm packages registry as follows.
npm i -D @japa/file-system@1.1.0
The next step is registering the plugin inside the plugins
array.
import { fileSystem } from '@japa/file-system'
import { configure, processCliArgs } from '@japa/runner'
configure({
...processCliArgs(process.argv.slice(2)),
...{
files: ['tests/**/*.spec.js'],
plugins: [fileSystem()]
}
})
const { fileSystem } = require('@japa/file-system')
const { configure, processCliArgs } = require('@japa/runner')
configure({
...processCliArgs(process.argv.slice(2)),
...{
files: ['tests/**/*.spec.js'],
plugins: [fileSystem()]
}
})
Basic usage
Once the plugin has been registered, you can access the fs
property from the
test context. The fs
property exposes the helper functions to read and write files. For example:
test('read rc file', async ({ fs }) => {
await fs.write('rc.json', JSON.stringify({
foo: 'bar'
}))
await runMethodThatNeedsRcFile()
})
A few things are happening here.
- First, you do not have to construct absolute paths to
write
the file. The file system plugin writes the files inside your operating system'stmp
directory. - You do not have to clean up any files or directories. The filesystem plugin will automatically perform the clean up after the test finishes.
You can specify a custom base directory or turn off the auto cleaning of files using the following configuration options.
{
plugins: [
fileSystem({
basePath: join(__dirname, './tmp'),
autoClean: false,
})
]
}
Assertions
The filesystem plugin extends the assert module and adds the following assertion methods to test file system operations quickly. All file system assertion methods are asynchronous.
fileExists/dirExists
Assert a file or a directory exists at a given location.
test('make controller', ({ assert, fs }) => {
await makeController(fs.basePath, 'users')
await assert.fileExists('controllers/users_controller.ts')
})
Argument | Type |
---|---|
filePath | String |
fileNotExists/dirNotExists
Assert a file or a directory should not exist at a given location.
test('make controller', ({ assert, fs }) => {
await makeController(fs.basePath, 'users', { dryRun: true })
await assert.fileNotExists('controllers/users_controller.ts')
})
Argument | Type |
---|---|
filePath | String |
fileEquals
Assert the contents of the file against a string value.
test('make controller', ({ assert, fs }) => {
await makeController(fs.basePath, 'users')
await assert.fileEquals('controllers/users_controller.ts', `
export default class UsersController {}
`)
})
Argument | Type |
---|---|
filePath | String |
contents | String |
fileContains
Assert the file contents to contain a substring or match a regular expression.
test('make controller', ({ assert, fs }) => {
await makeController(fs.basePath, 'users')
await assert.fileContains(
'controllers/users_controller.ts',
'class UsersController'
)
await assert.fileContains(
'controllers/users_controller.ts',
/class UsersController/
)
})
Argument | Type |
---|---|
filePath | String |
substring | String | Regexp |
fileSameAs
Assert the contents of the file matches the contents of another file.
test('make controller', ({ assert, fs }) => {
await makeController(fs.basePath, 'users')
await assert.fileSameAs(
'controllers/users_controller.ts',
'stubs/controller/make'
)
})
Argument | Type |
---|---|
filePath | String |
otherFilePath | String |
fileIsEmpty
Assert the file exists and is empty or has only whitespaces.
test('make preload file', ({ assert, fs }) => {
await makePreloadFile(fs.basePath, 'routes')
await assert.fileIsEmpty('start/routes.ts')
})
Argument | Type |
---|---|
filePath | String |
fileIsNotEmpty
Assert the file exists and is not empty.
test('make routes file', ({ assert, fs }) => {
await makeRoutesFile(fs.basePath)
await assert.fileIsNotEmpty('start/routes.ts')
})
Argument | Type |
---|---|
filePath | String |
hasFiles
Assert the root of the filesystem has all the mentioned files.
test('copy stubs', ({ assert, fs }) => {
await copyStubs(fs.basePath)
await assert.hasFiles([
'make/controller/main.stub',
'make/event/main.stub',
'make/listener/main.stub',
'make/command/main.stub',
])
})
Argument | Type |
---|---|
files | String[] |
doesNotHaveFiles
Assert the filesystem's root does not have any of the mentioned files.
test('copy stubs', ({ assert, fs }) => {
await copyStubs(fs.basePath, { dryRun: true })
await assert.doesNotHaveFiles([
'make/controller/main.stub',
'make/event/main.stub',
'make/listener/main.stub',
'make/command/main.stub',
])
})
Argument | Type |
---|---|
files | String[] |
dirIsEmpty
Assert a given directory is empty.
test('copy stubs', ({ assert, fs }) => {
await copyStubs(fs.basePath, { dryRun: true })
await assert.dirIsEmpty('make')
})
Argument | Type |
---|---|
dirPath | String? |
dirIsNotEmpty
Assert a given directory is not empty.
test('copy stubs', ({ assert, fs }) => {
await copyStubs(fs.basePath)
await assert.dirIsNotEmpty('make')
})
Argument | Type |
---|---|
dirPath | String? |
File system API
Following is the list of methods available on the ctx.fs
property. All methods accept relative paths.
cleanup
Remove the file system root directory. If you have turned off autoClean
, you might want to use this method as a hook to clean up files after each test.
test.group('Make files', (group) => {
group.each.setup(({ context }) => {
return () => context.fs.cleanup()
})
})
create
Create a file at a given location. The missing directories will be created automatically.
test('write rc file', async ({ fs }) => {
await fs.write('rc.json', JSON.stringify({
foo: 'bar'
}))
})
Argument | Type |
---|---|
filePath | String |
contents | String |
options | WriteFileOptions |
createJson
Same as create
, but writes the contents as JSON.
test('read rc file', async ({ fs }) => {
await fs.createJson('rc.json', {
foo: 'bar'
})
})
Argument | Type |
---|---|
filePath | String |
contents | Object |
options | JsonOutputOptions |
remove
Remove a file or a directory by its location.
test('delete rc file', async ({ fs }) => {
await fs.remove('rc.json')
})
Argument | Type |
---|---|
filePath | String |
rootExists
Check if the root directory of the file system exists. The method returns a boolean value.
test.group('Make files', (group) => {
group.each.setup(({ context }) => {
return async () => {
if (await context.fs.rootExists()) {
await context.fs.cleanup()
}
}
})
})
exists
Check if a directory exists. The method returns a boolean value.
test('do not update rc file', async ({ fs }) => {
if (await fs.exists('rc.json')) {
await fs.create('rc.json', contents)
}
})
Argument | Type |
---|---|
filePath | String |
contents
Returns the contents of a file as a string
test('read rc file', async ({ fs }) => {
const contents = await fs.contents('rc.json')
})
Argument | Type |
---|---|
filePath | String |
contentsJson
Parse the contents of a file as JSON and return it as an object.
test('read package.json file', async ({ fs }) => {
const contents = await fs.contentsJson('package.json')
console.log(contents.devDependencies)
})
stats
Get
fs.Stats
for a file by its location.
test('read rc file', async ({ fs }) => {
const stats = await fs.stats('rc.json')
})
Argument | Type |
---|---|
filePath | String |
readDir
Get an array of files for a directory. The return value is an array of EntryInfo objects.
test('copy files', async ({ fs }) => {
const entries = await fs.readDir('make')
entries.forEach((entry) => {
console.log(entry.path)
console.log(entry.fullPath)
console.log(entry.basename)
console.log(entry.stats)
})
})
Argument | Type |
---|---|
filePath | String |
adapter
The adapter
property is a reference to the
fs-extra package, and you can use it to perform file system operations not covered by the FileSystem
class.
test('copy files', async ({ fs }) => {
await fs.adapter.move(source, destination)
})