replace-in-file
Version:
A simple utility to quickly replace text in one or more files.
252 lines (225 loc) • 7.16 kB
JavaScript
import {expect, use, should} from 'chai'
import chaiAsPromised from 'chai-as-promised'
import {loadConfig, combineConfig, parseConfig} from './config.js'
import fs from 'node:fs'
//Enable should assertion style for usage with chai-as-promised
should()
use(chaiAsPromised)
/**
* Specs
*/
describe('helpers/config.js', () => {
/**
* Load config
*/
describe('loadConfig()', () => {
it('should error if no file is provided', () => {
return expect(loadConfig()).to.eventually.be.rejectedWith(Error)
})
it('should error when an invalid file is provided', () => {
return expect(loadConfig(42)).to.eventually.be.rejectedWith(Error)
})
it('should read config from a valid file', async () => {
//Test config
const config = {
files: ['file.txt'],
from: 'foo',
to: 'bar',
}
fs.writeFileSync('config.json', JSON.stringify(config), 'utf8')
//Load config
const cfg = await loadConfig('config.json')
expect(cfg).to.be.an('object')
expect(cfg.files).to.be.an('array')
expect(cfg.files).to.eql(config.files)
expect(cfg.from).to.equal(config.from)
expect(cfg.to).to.equal(config.to)
//Clean up
fs.unlinkSync('config.json')
})
})
/**
* Combine config
*/
describe('combineConfig()', () => {
it('should combine config with passed arguments', () => {
const argv = {
_: ['foo', 'bar', 'file.txt'],
ignore: ['ignore-file.txt'],
encoding: 'encoding',
disableGlobs: true,
dry: true,
quiet: true,
}
const combined = combineConfig({}, argv)
expect(combined.from).to.equal('foo')
expect(combined.to).to.equal('bar')
expect(combined.files).to.eql(['file.txt'])
expect(combined.ignore).to.eql(['ignore-file.txt'])
expect(combined.encoding).to.equal('encoding')
expect(combined.disableGlobs).to.be.true
expect(combined.dry).to.be.true
expect(combined.quiet).to.be.true
})
})
/**
* Parse config
*/
describe('parseConfig()', () => {
it('should error if no config is provided', () => {
expect(() => parseConfig()).to.throw(Error)
})
it('should error when an invalid config is provided', () => {
expect(() => parseConfig(42)).to.throw(Error)
expect(() => parseConfig(null)).to.throw(Error)
})
it('should error when an invalid `processor` is specified', () => {
expect(() => parseConfig({
processor: 'foo',
files: ['test1', 'test2', 'test3'],
from: [/re/g, /place/g],
to: ['b'],
})).to.throw(Error)
})
it('should error when an invalid `processorAsync` is specified', () => {
expect(() => parseConfig({
processorAsync: 'foo',
files: ['test1', 'test2', 'test3'],
from: [/re/g, /place/g],
to: ['b'],
})).to.throw(Error)
})
it('should error when `files` are not specified', () => {
expect(() => parseConfig({
from: [/re/g, /place/g],
to: ['b'],
})).to.throw(Error)
})
it('should error when `from` is not specified', () => {
expect(() => parseConfig({
files: ['test1', 'test2', 'test3'],
to: ['b'],
})).to.throw(Error)
})
it('should error when `to` is not specified', () => {
expect(() => parseConfig({
files: ['test1', 'test2', 'test3'],
from: [/re/g, /place/g],
})).to.throw(Error)
})
it('should error when an invalid `getTargetFile` handler is specified', () => {
expect(() => parseConfig({
getTargetFile: 'foo',
files: ['test1', 'test2', 'test3'],
from: [/re/g, /place/g],
to: ['b'],
})).to.throw(Error)
})
it('should convert `files` to an array', () => {
const parsed = parseConfig({
files: 'test1',
from: [/re/g, /place/g],
to: ['b'],
})
expect(parsed.files).to.eql(['test1'])
})
it('should default the `ignore` option to an empty array', () => {
const parsed = parseConfig({
files: ['test1'],
from: [/re/g, /place/g],
to: ['b'],
})
expect(parsed.ignore).to.eql([])
})
it('should convert the `ignore` option to an array', () => {
const parsed = parseConfig({
files: ['test1'],
from: [/re/g, /place/g],
to: ['b'],
ignore: 'ignore-file.txt',
})
expect(parsed.ignore).to.eql(['ignore-file.txt'])
})
it('should default `encoding` to utf-8 if not provided or invalid', () => {
const a = parseConfig({
files: ['test1'],
from: [/re/g, /place/g],
to: ['b'],
})
const b = parseConfig({
files: ['test1'],
from: [/re/g, /place/g],
to: ['b'],
encoding: 42,
})
const c = parseConfig({
files: ['test1'],
from: [/re/g, /place/g],
to: ['b'],
encoding: '',
})
expect(a.encoding).to.equal('utf-8')
expect(b.encoding).to.equal('utf-8')
expect(c.encoding).to.equal('utf-8')
})
it('should convert from regex if provided in JSON', async () => {
const parsed = parseConfig({
files: ['file.txt'],
from: '/foo/g',
to: 'bar',
})
expect(parsed.from).to.be.an.instanceof(RegExp)
})
it('should convert from an array of regexes if provided in JSON', async () => {
const parsed = parseConfig({
files: ['file.txt'],
from: ['/foo/g', '/baz/g', 'plain'],
to: 'bar',
})
expect(parsed.from).to.be.an.instanceof(Array)
expect(parsed.from[0]).to.be.an.instanceof(RegExp)
expect(parsed.from[1]).to.be.an.instanceof(RegExp)
expect(parsed.from[2]).to.equal('plain')
})
it('should not convert from regex if it is a regular string', async () => {
const parsed = parseConfig({
files: ['file.txt'],
from: '/foo',
to: 'bar',
})
expect(parsed.from).not.to.be.an.instanceof(RegExp)
expect(parsed.from).to.equal('/foo')
})
it('should overwrite the config defaults', () => {
const parsed = parseConfig({
files: 'test1',
from: [/re/g, /place/g],
to: ['b'],
ignore: 'ignore-file.txt',
encoding: 'encoding',
disableGlobs: true,
allowEmptyPaths: true,
countMatches: true,
verbose: true,
quiet: true,
dry: true,
glob: 'glob',
cwd: 'cwd',
fs: 'fs',
fsSync: 'fsSync',
})
expect(parsed.ignore).to.eql(['ignore-file.txt'])
expect(parsed.encoding).to.equal('encoding')
expect(parsed.disableGlobs).to.be.true
expect(parsed.allowEmptyPaths).to.be.true
expect(parsed.countMatches).to.be.true
expect(parsed.verbose).to.be.true
expect(parsed.quiet).to.be.true
expect(parsed.dry).to.be.true
expect(parsed.glob).to.equal('glob')
expect(parsed.cwd).to.equal('cwd')
expect(parsed.fs).to.equal('fs')
expect(parsed.fsSync).to.equal('fsSync')
})
})
})