@stryker-mutator/core
Version:
The extendable JavaScript mutation testing framework
249 lines • 11.8 kB
JavaScript
import path from 'path';
import { expect } from 'chai';
import sinon from 'sinon';
import { ProjectFile } from '../../../src/fs/index.js';
import { createFileSystemMock } from '../../helpers/producers.js';
describe(ProjectFile.name, () => {
let fileSystemMock;
beforeEach(() => {
fileSystemMock = createFileSystemMock();
});
describe(ProjectFile.prototype.readContent.name, () => {
it('should read the content from disk', async () => {
const sut = createSut({ name: 'foo.js' });
fileSystemMock.readFile.resolves('content');
const result = await sut.readContent();
expect(result).eq('content');
sinon.assert.calledOnceWithExactly(fileSystemMock.readFile, 'foo.js', 'utf-8');
});
it('should not read the content from disk when the content is set', async () => {
// Arrange
const sut = createSut();
sut.setContent('bar');
// Act
const result = await sut.readContent();
// Assert
expect(result).eq('bar');
sinon.assert.notCalled(fileSystemMock.readFile);
});
it('should read the content from disk only the first time', async () => {
// Arrange
const sut = createSut();
fileSystemMock.readFile.resolves('content');
// Act
await sut.readContent();
const result = await sut.readContent();
// Assert
expect(result).eq('content');
sinon.assert.calledOnceWithExactly(fileSystemMock.readFile, 'foo.js', 'utf-8');
});
});
describe(ProjectFile.prototype.readOriginal.name, () => {
it('should read the content from disk', async () => {
const sut = createSut({ name: 'foo.js' });
fileSystemMock.readFile.resolves('content');
const result = await sut.readOriginal();
expect(result).eq('content');
sinon.assert.calledOnceWithExactly(fileSystemMock.readFile, 'foo.js', 'utf-8');
});
it('should read the content from disk only the first time', async () => {
// Arrange
const sut = createSut({ name: 'foo.js' });
fileSystemMock.readFile.resolves('content');
// Act
await sut.readOriginal();
const result = await sut.readOriginal();
// Assert
expect(result).eq('content');
sinon.assert.calledOnceWithExactly(fileSystemMock.readFile, 'foo.js', 'utf-8');
});
it('should also cache original when readContent is called', async () => {
// Arrange
const sut = createSut({ name: 'foo.js' });
fileSystemMock.readFile.resolves('content');
// Act
await sut.readContent();
const result = await sut.readOriginal();
// Assert
expect(result).eq('content');
sinon.assert.calledOnceWithExactly(fileSystemMock.readFile, 'foo.js', 'utf-8');
});
it('should still read the content from disk when the content is set in-memory', async () => {
// Arrange
const sut = createSut();
fileSystemMock.readFile.resolves('original');
// Act
sut.setContent('bar');
const result = await sut.readOriginal();
// Assert
expect(result).eq('original');
});
});
describe(ProjectFile.prototype.toInstrumenterFile.name, () => {
it('should read content', async () => {
// Arrange
const mutate = [{ start: { column: 1, line: 2 }, end: { column: 3, line: 4 } }];
const sut = createSut({ name: 'bar.js', mutate });
fileSystemMock.readFile.resolves('original');
// Act
const result = await sut.toInstrumenterFile();
// Assert
const expected = { content: 'original', mutate, name: 'bar.js' };
expect(result).deep.eq(expected);
});
});
describe('hasChanges', () => {
it('should be false when nothing changed', () => {
const sut = createSut();
fileSystemMock.readFile.resolves('original');
expect(sut.hasChanges).false;
});
it('should be false when content is read but not overridden', async () => {
const sut = createSut();
fileSystemMock.readFile.resolves('original');
await sut.readOriginal();
expect(sut.hasChanges).false;
});
it('should be false when content is overridden with the same content', async () => {
const sut = createSut();
fileSystemMock.readFile.resolves('original');
await sut.readOriginal();
sut.setContent('original');
expect(sut.hasChanges).false;
});
it('should be true when content is overridden', async () => {
const sut = createSut();
sut.setContent('something');
expect(sut.hasChanges).true;
});
it('should be true when content is overridden after read', async () => {
const sut = createSut();
fileSystemMock.readFile.resolves('original');
await sut.readOriginal();
sut.setContent('');
expect(sut.hasChanges).true;
});
});
describe(ProjectFile.prototype.writeInPlace.name, () => {
it('should not do anything when there are no changes', async () => {
const sut = createSut();
await sut.writeInPlace();
sinon.assert.notCalled(fileSystemMock.writeFile);
});
it('should override current file when content was overridden', async () => {
const sut = createSut({ name: 'src/foo.js' });
sut.setContent('some content');
await sut.writeInPlace();
sinon.assert.calledOnceWithExactly(fileSystemMock.writeFile, 'src/foo.js', 'some content', 'utf-8');
});
it('should not do anything when the content written had no changes', async () => {
// Arrange
const sut = createSut({ name: 'src/foo.js' });
fileSystemMock.readFile.resolves('original');
await sut.readContent();
sut.setContent('original');
// Act
await sut.writeInPlace();
// Assert
sinon.assert.notCalled(fileSystemMock.writeFile);
});
});
describe(ProjectFile.prototype.writeToSandbox.name, () => {
it('should write to the sandbox', async () => {
// Arrange
const sut = createSut({ name: path.resolve('src', 'foo.js') });
sut.setContent('foo();');
// Act
const actualSandboxFile = await sut.writeToSandbox(path.resolve('.stryker-tmp', 'sandbox123'));
// Assert
expect(actualSandboxFile).eq(path.resolve('.stryker-tmp', 'sandbox123', 'src', 'foo.js'));
sinon.assert.calledOnceWithExactly(fileSystemMock.writeFile, actualSandboxFile, 'foo();', 'utf-8');
sinon.assert.notCalled(fileSystemMock.copyFile);
});
it('should resolve the correct file name when a sandbox outside of the current dir is used', async () => {
// Arrange
const sut = createSut({ name: path.resolve('src', 'foo.js') });
sut.setContent('foo();');
// Act
const actualSandboxFile = await sut.writeToSandbox(path.resolve('..', '.stryker-tmp', 'sandbox123'));
// Assert
expect(actualSandboxFile).eq(path.resolve('..', '.stryker-tmp', 'sandbox123', 'src', 'foo.js'));
});
it('should make the dir before write', async () => {
// Arrange
const sut = createSut({ name: path.resolve('src', 'foo.js') });
sut.setContent('foo();');
// Act
const actualSandboxFile = await sut.writeToSandbox(path.resolve('.stryker-tmp', 'sandbox123'));
// Assert
sinon.assert.calledOnceWithExactly(fileSystemMock.mkdir, path.dirname(actualSandboxFile), { recursive: true });
sinon.assert.callOrder(fileSystemMock.mkdir, fileSystemMock.writeFile);
});
it('should copy the file instead of reading/writing when the file is not read to memory', async () => {
// Arrange
const originalFileName = path.resolve('src', 'foo.js');
const sut = createSut({ name: originalFileName });
// Act
const actualSandboxFile = await sut.writeToSandbox(path.resolve('.stryker-tmp', 'sandbox123'));
// Assert
expect(actualSandboxFile).eq(path.resolve('.stryker-tmp', 'sandbox123', 'src', 'foo.js'));
sinon.assert.calledOnceWithExactly(fileSystemMock.copyFile, originalFileName, actualSandboxFile);
sinon.assert.notCalled(fileSystemMock.writeFile);
});
});
describe(ProjectFile.prototype.backupTo.name, () => {
it('should write to the backup', async () => {
// Arrange
const sut = createSut({ name: path.resolve('src', 'foo.js') });
fileSystemMock.readFile.resolves('original');
await sut.readOriginal();
// Act
const actualBackupFile = await sut.backupTo(path.resolve('.stryker-tmp', 'backup123'));
// Assert
expect(actualBackupFile).eq(path.resolve('.stryker-tmp', 'backup123', 'src', 'foo.js'));
sinon.assert.calledOnceWithExactly(fileSystemMock.writeFile, actualBackupFile, 'original');
sinon.assert.notCalled(fileSystemMock.copyFile);
});
it('should make the dir before write', async () => {
// Arrange
const sut = createSut({ name: path.resolve('src', 'foo.js') });
fileSystemMock.readFile.resolves('original');
await sut.readOriginal();
// Act
const actualBackupFile = await sut.backupTo(path.resolve('.stryker-tmp', 'backup123'));
// Assert
sinon.assert.calledOnceWithExactly(fileSystemMock.mkdir, path.dirname(actualBackupFile), { recursive: true });
sinon.assert.callOrder(fileSystemMock.mkdir, fileSystemMock.writeFile);
});
it('should copy the file instead of reading/writing when the file is present in memory', async () => {
// Arrange
const originalFileName = path.resolve('src', 'foo.js');
const sut = createSut({ name: originalFileName });
// Act
const actualBackupFile = await sut.backupTo(path.resolve('.stryker-tmp', 'backup-123'));
// Assert
expect(actualBackupFile).eq(path.resolve('.stryker-tmp', 'backup-123', 'src', 'foo.js'));
sinon.assert.calledOnceWithExactly(fileSystemMock.copyFile, originalFileName, actualBackupFile);
sinon.assert.notCalled(fileSystemMock.writeFile);
});
it('should ignore in-memory overrides', async () => {
// Arrange
const sut = createSut();
sut.setContent('override!');
// Act
await sut.backupTo(path.resolve('.stryker-tmp', 'backup-123'));
// Assert
sinon.assert.calledOnce(fileSystemMock.copyFile);
sinon.assert.notCalled(fileSystemMock.writeFile);
});
});
function createSut(overrides) {
const { name, mutate } = {
name: 'foo.js',
mutate: true,
...overrides,
};
return new ProjectFile(fileSystemMock, name, mutate);
}
});
//# sourceMappingURL=project-file.spec.js.map