Skip to content

Commit

Permalink
CSharpFileCreator uses TemplateConfiguration
Browse files Browse the repository at this point in the history
- removed vscode dependency from TemplateConfiguration and CSharpFileCreator
- updated tests
  • Loading branch information
Sante Barbuto committed May 11, 2023
1 parent 3680088 commit e7e61b0
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 175 deletions.
15 changes: 7 additions & 8 deletions src/creator/cShaprFileCreator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import * as vscode from 'vscode';

import { TemplateType } from '../template/templateType';
import { ExtensionError } from '../util';
import Template from '../template/template';
Expand All @@ -17,9 +15,11 @@ export type CreatedFile = {

export default class CSharpFileCreator {
private _template: TemplateType;
private _templateConfiguration: TemplateConfiguration;

private constructor(templateTypes: TemplateType) {
this._template = templateTypes;
private constructor(templateConfiguration: TemplateConfiguration) {
this._template = templateConfiguration.getTemplateType();
this._templateConfiguration = templateConfiguration;
}

public async create(templatesPath: string, pathWithoutExtension: string, newFilename: string): Promise<Result<CreatedFile>> {
Expand All @@ -40,8 +40,7 @@ export default class CSharpFileCreator {
return Result.error<CreatedFile>(statuses.readingTemplateError, error.toString());
}

const templateConf = TemplateConfiguration.create(this._template, vscode.workspace.getConfiguration());
const template = new Template(this._template, templateContent, fileScopedNamespaceConverter, templateConf);
const template = new Template(this._template, templateContent, fileScopedNamespaceConverter, this._templateConfiguration);
const namespaceDetector = new NamespaceDetector(pathWithoutExtension);
const namespace = await namespaceDetector.getNamespace();

Expand All @@ -64,7 +63,7 @@ export default class CSharpFileCreator {
return Result.ok<CreatedFile>({ filePath: destinationFilePath, cursorPositionArray: cursorPositionArray });
}

public static create(template: TemplateType): Result<CSharpFileCreator> {
return Result.ok<CSharpFileCreator>(new CSharpFileCreator(template));
public static create(templateConfiguration: TemplateConfiguration): Result<CSharpFileCreator> {
return Result.ok<CSharpFileCreator>(new CSharpFileCreator(templateConfiguration));
}
}
9 changes: 8 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { log } from './util';
import CSharpFileCreator from './creator/cShaprFileCreator';
import Maybe from './common/maybe';
import { CommandMapping, createExtensionMappings } from './commandMapping';
import TemplateConfiguration from './template/templateConfiguration';

const EXTENSION_NAME = 'csharpextensions';

Expand Down Expand Up @@ -90,8 +91,12 @@ export class Extension {
const pathWithoutExtension = `${incomingPath}${path.sep}${newFilename}`;

const { templates } = mapping;
const configuration = vscode.workspace.getConfiguration();
const eol = configuration.get('file.eol', EOL);
const includeNamespaces = configuration.get(`${EXTENSION_NAME}.includeNamespaces`, true);

const createdFilesResult = await Promise.all(templates.map(async template => {
return CSharpFileCreator.create(template)
return CSharpFileCreator.create(TemplateConfiguration.create(template, eol, includeNamespaces))
.AndThen(async creator => await creator.create(templatesPath, pathWithoutExtension, newFilename));
}));

Expand All @@ -102,6 +107,8 @@ export class Extension {

log(error);
vscode.window.showErrorMessage(error);

return;
}

const files = createdFilesResult.map(result => result.value()).sort((cf1, cf2) => {
Expand Down
21 changes: 10 additions & 11 deletions src/template/templateConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,43 @@
import { EOL } from 'os';
import { WorkspaceConfiguration } from 'vscode';

import { ExtensionError } from '../util';
import { TemplateType } from './templateType';

export default class TemplateConfiguration {
private _templateType: TemplateType;
private _includeNamespaces: boolean;
private _eolSettings: string;
private _requiredUsings: Array<string>;
private _optionalUsings: Array<string>;

constructor(includeNamespaces: boolean, eolSettings: string, requiredUsings: Array<string>, optionalUsings: Array<string>) {
private constructor(templateType: TemplateType, includeNamespaces: boolean, eolSettings: string, requiredUsings: Array<string>, optionalUsings: Array<string>) {
this._templateType = templateType;
this._includeNamespaces = includeNamespaces;
this._eolSettings = eolSettings;
this._requiredUsings = requiredUsings;
this._optionalUsings = optionalUsings;
}

public getTemplateType(): TemplateType { return this._templateType; }
public getIncludeNamespaces(): boolean { return this._includeNamespaces; }
public getEolSettings(): string { return this._eolSettings; }
public getRequiredUsings(): Array<string> { return this._requiredUsings; }
public getOptionalUsings(): Array<string> { return this._optionalUsings; }

public static create(type: TemplateType, workspaceConfiguration: WorkspaceConfiguration): TemplateConfiguration {
const eolSettings = TemplateConfiguration.getEolSetting(workspaceConfiguration);
const includeNamespaces = workspaceConfiguration.get('csharpextensions.includeNamespaces', true);
public static create(type: TemplateType, eol: string, includeNamespaces: boolean): TemplateConfiguration {
const eolSettings = TemplateConfiguration.getEolSetting(eol);

const requiredUsings = TemplateConfiguration.retrieveRequiredUsings(type);
const optionalUsings = TemplateConfiguration.retrieveOptionalUsings(type);

return new TemplateConfiguration(includeNamespaces, eolSettings, requiredUsings, optionalUsings);
return new TemplateConfiguration(type, includeNamespaces, eolSettings, requiredUsings, optionalUsings);
}

private static getEolSetting(workspaceConfiguration: WorkspaceConfiguration): string {
const eolSetting = workspaceConfiguration.get('files.eol', EOL);

switch (eolSetting) {
private static getEolSetting(eol: string): string {
switch (eol) {
case '\n':
case '\r\n':
return eolSetting;
return eol;
case 'auto':
default:
return EOL;
Expand Down
103 changes: 103 additions & 0 deletions test/suite/unit/creator/cSharpFileCreator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import * as assert from 'assert';
import { beforeEach, afterEach } from 'mocha';
import { EOL } from 'os';
import { sep } from 'path';
import * as sinon from 'sinon';

import CSharpFileCreator from '../../../../src/creator/cShaprFileCreator';
import TemplateConfiguration from '../../../../src/template/templateConfiguration';
import { TemplateType } from '../../../../src/template/templateType';
import statuses from '../../../../src/creator/fileCreatorStatus';
import FileHandler from '../../../../src/io/fileHandler';

suite('CSharpFileCreator', () => {
let fakeFileHandler: {
fileExists: () => Promise<boolean>,
read: () => Promise<string>,
write: () => Promise<void>,
};

const templatesPath = 'templates';
const newFilename = 'File';
const pathWithoutExtension = `test${sep}suite${sep}unit${sep}creator${sep}${newFilename}`;
const destinationFilePath = `${pathWithoutExtension}.cs`;

beforeEach(() => {
fakeFileHandler = {
fileExists: sinon.fake.resolves(false),
read: sinon.fake.resolves('template content'),
write: sinon.fake.resolves(undefined),
};
});

afterEach(() => {
sinon.restore();
sinon.reset();
});

test('Create when a file exists, returns FileExistingError', async () => {
fakeFileHandler.fileExists = sinon.fake.resolves(true);
sinon.replace(FileHandler, 'fileExists', fakeFileHandler.fileExists);
sinon.replace(FileHandler, 'read', fakeFileHandler.read);
sinon.replace(FileHandler, 'write', fakeFileHandler.write);
const useFileScopedNamespace = false;
const error = `File already exists: ${destinationFilePath}`;


const configuration = TemplateConfiguration.create(TemplateType.Class, EOL, useFileScopedNamespace);
const fileCreator = CSharpFileCreator.create(configuration).value();

const result = await fileCreator.create(templatesPath, pathWithoutExtension, newFilename);

assert.strictEqual(result.isErr(), true);
assert.strictEqual(result.isOk(), false);
assert.strictEqual(result.status(), statuses.fileExistingError);
assert.strictEqual(result.info(), error);
});

test('Create when template cannot be read, returns ReadingTemplateError', async () => {
fakeFileHandler.read= sinon.fake.rejects('Error reading template');
sinon.replace(FileHandler, 'fileExists', fakeFileHandler.fileExists);
sinon.replace(FileHandler, 'read', fakeFileHandler.read);
sinon.replace(FileHandler, 'write', fakeFileHandler.write);
const configuration = TemplateConfiguration.create(TemplateType.Class, EOL, false);
const fileCreator = CSharpFileCreator.create(configuration).value();

const result = await fileCreator.create(templatesPath, pathWithoutExtension, newFilename);

assert.strictEqual(result.isErr(), true);
assert.strictEqual(result.isOk(), false);
assert.strictEqual(result.status(),statuses.readingTemplateError);
assert.strictEqual(result.info(), 'Error: Error reading template');
});

test('Create when file cannot be written, returns WritingFileError', async () => {
fakeFileHandler.write= sinon.fake.rejects('write error');
sinon.replace(FileHandler, 'fileExists', fakeFileHandler.fileExists);
sinon.replace(FileHandler, 'read', fakeFileHandler.read);
sinon.replace(FileHandler, 'write', fakeFileHandler.write);
const configuration = TemplateConfiguration.create(TemplateType.Class, EOL, false);
const fileCreator = CSharpFileCreator.create(configuration).value();

const result = await fileCreator.create(templatesPath, pathWithoutExtension, newFilename);

assert.strictEqual(result.isOk(), false);
assert.strictEqual(result.isErr(), true);
assert.strictEqual(result.status(),statuses.writingFileError);
assert.strictEqual(result.info(), 'Error: write error');
});

test('Create file successfully', async () => {
sinon.replace(FileHandler, 'fileExists', fakeFileHandler.fileExists);
sinon.replace(FileHandler, 'read', fakeFileHandler.read);
sinon.replace(FileHandler, 'write', fakeFileHandler.write);
const configuration = TemplateConfiguration.create(TemplateType.Class, EOL, false);
const fileCreator = CSharpFileCreator.create(configuration).value();

const result = await fileCreator.create(templatesPath, pathWithoutExtension, newFilename);

assert(result.isOk());
assert.strictEqual(result.value().filePath, destinationFilePath);
assert.strictEqual(result.value().cursorPositionArray, null);
});
});
Loading

0 comments on commit e7e61b0

Please sign in to comment.