From c51e3716f3f9fdeebec5491dac63b08b01496459 Mon Sep 17 00:00:00 2001 From: Glavin Wiechert Date: Mon, 9 Apr 2018 01:42:31 -0300 Subject: [PATCH] See #58. Add configuration options to dependencies --- jest.config.js | 2 +- src/DependencyManager/Dependency.ts | 30 ++++-- src/DependencyManager/DependencyFactory.ts | 14 +-- src/DependencyManager/DependencyManager.ts | 101 +++++++++++++----- src/DependencyManager/ExecutableDependency.ts | 27 +++-- src/DependencyManager/NodeDependency.ts | 8 +- src/beautifier.ts | 72 ++++++------- .../DependencyManager.spec.ts | 34 +++--- .../ExecutableDependency.spec.ts | 89 +++++++++------ test/DependencyManager/NodeDependency.spec.ts | 8 +- test/beautifier/dependency.spec.ts | 11 +- 11 files changed, 252 insertions(+), 144 deletions(-) diff --git a/jest.config.js b/jest.config.js index 1028642d..332cae6c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -16,7 +16,7 @@ module.exports = { "/node_modules/", ], moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - collectCoverage: true, + // collectCoverage: true, coverageReporters: ["json", "lcov", "text", "html"], coveragePathIgnorePatterns: [ "/__mocks__/", diff --git a/src/DependencyManager/Dependency.ts b/src/DependencyManager/Dependency.ts index 9bed859c..55baa92f 100644 --- a/src/DependencyManager/Dependency.ts +++ b/src/DependencyManager/Dependency.ts @@ -5,7 +5,7 @@ export abstract class Dependency { private _version?: Version; private _errors: Error[] = []; - constructor(protected options: DependencyOptions) {} + constructor(protected definition: DependencyDefinition, protected options: DependencyOptions) {} public load(): Promise { if (this.isInstalled) { @@ -44,7 +44,7 @@ export abstract class Dependency { } private versionFromText(text: string): string | undefined { - const { parseVersion } = this.options; + const { parseVersion } = this.definition; if (!parseVersion) { return text; } @@ -93,11 +93,11 @@ export abstract class Dependency { } public get name(): string { - return this.options.name; + return this.definition.name; } public get required(): boolean { - return !Boolean(this.options.optional); + return !Boolean(this.definition.optional); } public get version(): Version | undefined { @@ -109,7 +109,7 @@ export abstract class Dependency { } } -export interface BaseDependencyOptions { +export interface BaseDependencyDefinition { // tslint:disable-next-line:no-reserved-keywords type: DependencyType; name: string; @@ -132,14 +132,14 @@ export type DependencyVersionParserFunction = ( text: string ) => string | undefined; -export interface NodeDependencyOptions extends BaseDependencyOptions { +export interface NodeDependencyDefinition extends BaseDependencyDefinition { // tslint:disable-next-line:no-reserved-keywords type: DependencyType.Node; // tslint:disable-next-line:no-reserved-keywords package: string; } -export interface ExecutableDependencyOptions extends BaseDependencyOptions { +export interface ExecutableDependencyDefinition extends BaseDependencyDefinition { // tslint:disable-next-line:no-reserved-keywords type: DependencyType.Executable; program: string; @@ -149,6 +149,16 @@ export interface ExecutableDependencyOptions extends BaseDependencyOptions { }; } -export type DependencyOptions = - | NodeDependencyOptions - | ExecutableDependencyOptions; +export type DependencyDefinition = + | NodeDependencyDefinition + | ExecutableDependencyDefinition; + +export interface DependencyOptions { + // prefer_beautifier_config?: string; + // executables?: { [executableName: string]: ExecutableConfig }; + path?: string; +} + +// export interface ExecutableConfig { +// path?: string; +// } diff --git a/src/DependencyManager/DependencyFactory.ts b/src/DependencyManager/DependencyFactory.ts index d892ad97..1c7cbd81 100644 --- a/src/DependencyManager/DependencyFactory.ts +++ b/src/DependencyManager/DependencyFactory.ts @@ -1,20 +1,20 @@ -import { Dependency, DependencyType, DependencyOptions } from "./Dependency"; +import { Dependency, DependencyType, DependencyDefinition, DependencyOptions } from "./Dependency"; import { NodeDependency } from "./NodeDependency"; import { ExecutableDependency } from "./ExecutableDependency"; export class DependencyFactory { - constructor(private options: DependencyOptions) {} + constructor(private definition: DependencyDefinition, private options: DependencyOptions) {} public dependency(): Dependency { - const { options } = this; - switch (options.type) { + const { definition, options } = this; + switch (definition.type) { case DependencyType.Node: - return new NodeDependency(options); + return new NodeDependency(definition, options); case DependencyType.Executable: - return new ExecutableDependency(options); + return new ExecutableDependency(definition, options); default: throw new Error( - `Dependency type not found for: ${JSON.stringify(options)}` + `Dependency type not found for: ${JSON.stringify(definition)}` ); } } diff --git a/src/DependencyManager/DependencyManager.ts b/src/DependencyManager/DependencyManager.ts index e3f5910b..7b47de30 100644 --- a/src/DependencyManager/DependencyManager.ts +++ b/src/DependencyManager/DependencyManager.ts @@ -1,47 +1,94 @@ +// tslint:disable:newspaper-order // tslint:disable:no-reserved-keywords import { DependencyFactory } from "./DependencyFactory"; -import { Dependency, DependencyOptions } from "./Dependency"; +import { + Dependency, + DependencyDefinition, + DependencyOptions, +} from "./Dependency"; export class DependencyManager { - private readonly dependencies: Dependency[]; - private readonly lookup: { - [name: string]: Dependency; - }; + private static registry: DependencyRegistry = {}; + + public static clearRegistry(): void { + this.registry = {}; + } + + constructor( + private beautifierName: string, + private dependencyDefinitions: DependencyDefinition[] = [], + private options: LanguageDependencyOptions = {} + ) { + this.initializeDependencies(); + } + + private initializeDependencies(): void { + const lookup = DependencyManager.registry; + const beautifierLookup = lookup[this.beautifierName] || {}; + lookup[this.beautifierName] = beautifierLookup; - constructor(dependencies: DependencyOptions[]) { - this.dependencies = dependencies.map(dependency => - new DependencyFactory(dependency).dependency() - ); - this.lookup = this.dependencies.reduce( - (lookup, dep) => ({ - ...lookup, - [dep.name]: dep, - }), - {} - ); + this.dependencyDefinitions.forEach(def => { + const { name: dependencyName } = def; + const options = this.optionsForDependency(dependencyName); + const optionsKey = this.keyForOptions(options); + const depLookup = beautifierLookup[dependencyName] || {}; + beautifierLookup[dependencyName] = depLookup; + depLookup[optionsKey] = + depLookup[optionsKey] || this.createDependency(def, options); + }); + } + + private optionsForDependency(dependencyName: string): DependencyOptions { + return this.options[dependencyName]; } public has(name: string): boolean { return Boolean(this.get(name)); } - public get(name: string): T { - const dep = this.lookup[name] as T | undefined; + public load(): Promise { + return Promise.all( + this.dependencyDefinitions + .map(def => this.get(def.name)) + .map(dep => dep.load()) + ).then(() => true); + } + + public get(dependencyName: string): T { + const options = this.optionsForDependency(dependencyName); + const optionsKey = this.keyForOptions(options); + const lookup = this.registry[dependencyName] || {}; + const dep = lookup[optionsKey] as T | undefined; if (!dep) { - throw new Error(`Dependency with name ${name} not found.`); + throw new Error(`Dependency with name ${dependencyName} not found.`); } return dep; } - public load(): Promise { - return Promise.all( - this.dependencies.map(dep => { - return dep.load(); - }) - ).then(() => true); + protected get registry(): DependencyRegistry[string] { + return DependencyManager.registry[this.beautifierName]; + } + + protected createDependency( + definition: DependencyDefinition, + options: DependencyOptions + ): Dependency { + return new DependencyFactory(definition, options).dependency(); + } + + private keyForOptions(options: DependencyOptions = {}): string { + return JSON.stringify(options); } } -export interface DependencyMap { - [name: string]: Dependency; +export interface LanguageDependencyOptions { + [dependencyName: string]: DependencyOptions; +} + +export interface DependencyRegistry { + [beautifierName: string]: { + [dependencyName: string]: { + [optionsKey: string]: Dependency; + }; + }; } diff --git a/src/DependencyManager/ExecutableDependency.ts b/src/DependencyManager/ExecutableDependency.ts index 6089c2f0..bf4a0d93 100644 --- a/src/DependencyManager/ExecutableDependency.ts +++ b/src/DependencyManager/ExecutableDependency.ts @@ -1,10 +1,17 @@ import { spawn, SpawnOptions } from "child_process"; -import { Dependency, ExecutableDependencyOptions } from "./Dependency"; +import { + Dependency, + ExecutableDependencyDefinition, + DependencyOptions, +} from "./Dependency"; export class ExecutableDependency extends Dependency { - constructor(protected options: ExecutableDependencyOptions) { - super(options); + constructor( + protected definition: ExecutableDependencyDefinition, + options: DependencyOptions = {} + ) { + super(definition, options); } protected loadVersion() { @@ -12,7 +19,7 @@ export class ExecutableDependency extends Dependency { } private get versionArgs(): string[] { - return this.options.versionArgs || ["--version"]; + return this.definition.versionArgs || ["--version"]; } public run({ @@ -25,7 +32,7 @@ export class ExecutableDependency extends Dependency { stdin?: any; }): Promise { return this.resolveArgs(args).then(finalArgs => - this.spawn({ exe: this.program, args: finalArgs, options, stdin }) + this.spawn({ exe: this.pathOrProgram, args: finalArgs, options, stdin }) ); } @@ -35,8 +42,16 @@ export class ExecutableDependency extends Dependency { ); } + private get pathOrProgram(): string { + return this.programPath || this.program; + } + private get program(): string { - return this.options.program; + return this.definition.program; + } + + private get programPath(): string | undefined { + return this.options.path; } private spawn({ diff --git a/src/DependencyManager/NodeDependency.ts b/src/DependencyManager/NodeDependency.ts index 670ecb4c..7168c9fd 100644 --- a/src/DependencyManager/NodeDependency.ts +++ b/src/DependencyManager/NodeDependency.ts @@ -1,11 +1,11 @@ -import { Dependency, NodeDependencyOptions } from "./Dependency"; +import { Dependency, NodeDependencyDefinition, DependencyOptions } from "./Dependency"; // tslint:disable-next-line:no-require-imports no-var-requires const requireg = require("requireg"); export class NodeDependency extends Dependency { - constructor(protected options: NodeDependencyOptions) { - super(options); + constructor(protected definition: NodeDependencyDefinition, options: DependencyOptions = {}) { + super(definition, options); } protected loadVersion() { @@ -65,6 +65,6 @@ export class NodeDependency extends Dependency { } private get packageName(): string { - return this.options.package; + return this.definition.package; } } diff --git a/src/beautifier.ts b/src/beautifier.ts index d35d1ac8..efef0d1f 100644 --- a/src/beautifier.ts +++ b/src/beautifier.ts @@ -3,7 +3,7 @@ import * as _ from "lodash"; import { Language } from "./language"; import { OptionsRegistry } from "./options"; import { InlineFlagManager } from "./InlineFlagManager"; -import { DependencyOptions, DependencyManager } from "./DependencyManager"; +import { DependencyDefinition, DependencyManager } from "./DependencyManager"; /** New name to rename the option (key) to. @@ -162,17 +162,13 @@ export interface Beautifier { /** * Runtime dependencies of the beautifier. */ - dependencies?: DependencyOptions[]; + dependencies?: DependencyDefinition[]; /** Beautify the given code with the beautifier. */ beautify(data: BeautifierBeautifyData): Promise; } -export interface BeautifierInternal extends Beautifier { - dependencyManager: DependencyManager; -} - /** Beautifier */ @@ -188,7 +184,7 @@ export class Unibeautify { /** */ - private beautifiers: BeautifierInternal[] = []; + private beautifiers: Beautifier[] = []; /** * Get loaded languages which have a loaded beautifier supporting the given option @@ -286,7 +282,7 @@ export class Unibeautify { } return this.beautifyWithBeautifiers({ - beautifiers: selectedBeautifiers as BeautifierInternal[], + beautifiers: selectedBeautifiers as Beautifier[], fileExtension: data.fileExtension, langOptions, language: lang, @@ -314,14 +310,12 @@ export class Unibeautify { lang: Language, langOptions: OptionValues ): { - selectedBeautifiers: (BeautifierInternal | undefined)[]; + selectedBeautifiers: (Beautifier | undefined)[]; missingBeautifierName: string | undefined; } { - const allBeautifiers: BeautifierInternal[] = this.getBeautifiersForLanguage( - lang - ); + const allBeautifiers: Beautifier[] = this.getBeautifiersForLanguage(lang); const beautifierNames: string[] = langOptions.beautifiers || []; - const selectedBeautifiers: (BeautifierInternal | undefined)[] = + const selectedBeautifiers: (Beautifier | undefined)[] = beautifierNames.length > 0 ? this.beautifiersWithNames(beautifierNames, allBeautifiers) : allBeautifiers; @@ -337,14 +331,14 @@ export class Unibeautify { private beautifiersWithNames( names: string[], - beautifiers: BeautifierInternal[] - ): (BeautifierInternal | undefined)[] { + beautifiers: Beautifier[] + ): (Beautifier | undefined)[] { const beautifiersByName = beautifiers.reduce( (index, current) => { index[current.name] = current; return index; }, - {} as { [beautifierName: string]: BeautifierInternal } + {} as { [beautifierName: string]: Beautifier } ); return names.map(name => beautifiersByName[name]); } @@ -357,7 +351,7 @@ export class Unibeautify { projectPath, text, }: { - beautifiers: BeautifierInternal[]; + beautifiers: Beautifier[]; language: Language; langOptions: OptionValues; text: BeautifyData["text"]; @@ -365,14 +359,18 @@ export class Unibeautify { projectPath: BeautifyData["projectPath"]; }): Promise { return beautifiers.reduce( - (promise: Promise, beautifier: BeautifierInternal) => { + (promise: Promise, beautifier: Beautifier) => { const options: OptionValues = Unibeautify.getOptionsForBeautifier( beautifier, language, langOptions ); return promise.then(currentText => { - const { dependencyManager } = beautifier; + const dependencyManager = new DependencyManager( + beautifier.name, + beautifier.dependencies || [], + langOptions + ); return dependencyManager.load().then(() => { return beautifier .beautify({ @@ -384,10 +382,7 @@ export class Unibeautify { Promise, text: currentText, }) - .then(newText => { - const manager = new InlineFlagManager(currentText, newText); - return manager.text; - }); + .then(newText => this.handleInlineFlags(currentText, newText)); }); }); }, @@ -395,6 +390,11 @@ export class Unibeautify { ); } + private handleInlineFlags(currentText: string, newText: string): string { + const manager = new InlineFlagManager(currentText, newText); + return manager.text; + } + /** Find and return the appropriate Languages that match any of the given filter criteria. An empty array will be returned if there are no matches. @@ -493,11 +493,9 @@ export class Unibeautify { /** * Find and return the appropriate Beautifiers for the given Language. */ - public getBeautifiersForLanguage(language: Language): BeautifierInternal[] { - return _.filter( - this.beautifiers, - (beautifier: BeautifierInternal): boolean => - this.doesBeautifierSupportLanguage(beautifier, language) + public getBeautifiersForLanguage(language: Language): Beautifier[] { + return _.filter(this.beautifiers, (beautifier: Beautifier): boolean => + this.doesBeautifierSupportLanguage(beautifier, language) ); } @@ -627,10 +625,19 @@ export class Unibeautify { Load a Beautifier */ public loadBeautifier(beautifier: Beautifier): Unibeautify { - this.beautifiers.push(this.internalBeautifier(beautifier)); + this.validateBeautifier(beautifier); + this.beautifiers.push(beautifier); return this; } + private validateBeautifier(beautifier: any = {}): void { + if (!beautifier.name) { + throw new Error('Beautifier is missing a "name" property.'); + } + // tslint:disable-next-line:no-unused-expression + new DependencyManager(beautifier.name, beautifier.dependencies, {}); + } + /** Load multiple beautifiers. */ @@ -639,13 +646,6 @@ export class Unibeautify { return this; } - private internalBeautifier(beautifier: Beautifier): BeautifierInternal { - return { - ...beautifier, - dependencyManager: new DependencyManager(beautifier.dependencies || []), - }; - } - /** Load a Language */ diff --git a/test/DependencyManager/DependencyManager.spec.ts b/test/DependencyManager/DependencyManager.spec.ts index 3f7eddb3..323b34c0 100644 --- a/test/DependencyManager/DependencyManager.spec.ts +++ b/test/DependencyManager/DependencyManager.spec.ts @@ -1,18 +1,24 @@ import { - DependencyOptions, + DependencyDefinition, DependencyType, DependencyManager, NodeDependency, } from "../../src/DependencyManager"; +beforeEach(() => { + DependencyManager.clearRegistry(); +}); + +const beautifierName = "beautifierName"; + test("should fail to load dependencies", async () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "NotFound", package: "notfound", type: DependencyType.Node, }; - const manager = new DependencyManager([options]); + const manager = new DependencyManager(beautifierName, [options]); return await manager.load().catch(error => { expect(error.message).toMatch( @@ -25,12 +31,12 @@ test("should fail to load dependencies", async () => { describe("successfully loads dependency", () => { test("should successfully load dependencies", async () => { expect.assertions(1); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "FakeDep", package: "fakedep", type: DependencyType.Node, }; - const manager = new DependencyManager([options]); + const manager = new DependencyManager(beautifierName, [options]); return await expect(manager.load()).resolves.toBe(true); }); @@ -38,12 +44,12 @@ describe("successfully loads dependency", () => { test("should have package", async () => { expect.assertions(1); const packageName = "fakedep"; - const options: DependencyOptions = { + const options: DependencyDefinition = { name: packageName, package: packageName, type: DependencyType.Node, }; - const manager = new DependencyManager([options]); + const manager = new DependencyManager(beautifierName, [options]); return await manager.load().then(() => { expect(manager.has(packageName)).toBe(true); @@ -53,12 +59,12 @@ describe("successfully loads dependency", () => { test("should get package", async () => { expect.assertions(1); const packageName = "fakedep"; - const options: DependencyOptions = { + const options: DependencyDefinition = { name: packageName, package: packageName, type: DependencyType.Node, }; - const manager = new DependencyManager([options]); + const manager = new DependencyManager(beautifierName, [options]); return await manager.load().then(() => { const dep = manager.get(packageName); @@ -69,12 +75,12 @@ describe("successfully loads dependency", () => { test("should get package vesion", async () => { expect.assertions(6); const packageName = "fakedep"; - const options: DependencyOptions = { + const options: DependencyDefinition = { name: packageName, package: packageName, type: DependencyType.Node, }; - const manager = new DependencyManager([options]); + const manager = new DependencyManager(beautifierName, [options]); return await manager.load().then(() => { expect(manager.has(packageName)).toBe(true); @@ -93,11 +99,11 @@ describe("successfully loads dependency", () => { }); describe("get", () => { - test("should throw error if package not found", async () => { + test("should throw error if package not found", () => { expect.assertions(1); const packageName = "fakedep"; - const manager = new DependencyManager([]); - return await manager.load().then(() => { + const manager = new DependencyManager(beautifierName, []); + return manager.load().then(() => { expect(() => manager.get(packageName)).toThrowError(); }); }); diff --git a/test/DependencyManager/ExecutableDependency.spec.ts b/test/DependencyManager/ExecutableDependency.spec.ts index 95e7a234..93d8fea3 100644 --- a/test/DependencyManager/ExecutableDependency.spec.ts +++ b/test/DependencyManager/ExecutableDependency.spec.ts @@ -1,33 +1,58 @@ import { ExecutableDependency, DependencyType, + DependencyDefinition, DependencyOptions, } from "../../src/DependencyManager"; -test("should fail to load Executable dependency", async () => { - expect.assertions(4); - const options: DependencyOptions = { - name: "NotFound", - program: "NotFound", - type: DependencyType.Executable, - }; - const dependency = new ExecutableDependency(options); +describe("fail to load Executable dependency", () => { + test("should fail to load Executable dependency", async () => { + expect.assertions(4); + const def: DependencyDefinition = { + name: "NotFound", + program: "NotFound", + type: DependencyType.Executable, + }; + const dependency = new ExecutableDependency(def); - return await dependency.load().catch(error => { - expect(error.message).toMatch( - 'Dependency "NotFound" is required and not installed.' - ); - expect(error.message).toMatch("spawn NotFound ENOENT"); - expect(dependency.isInstalled).toBe(false); - expect(dependency.errors).toHaveLength(1); + return await dependency.load().catch(error => { + expect(error.message).toMatch( + 'Dependency "NotFound" is required and not installed.' + ); + expect(error.message).toMatch("spawn NotFound ENOENT"); + expect(dependency.isInstalled).toBe(false); + expect(dependency.errors).toHaveLength(1); + }); + }); + + test("should fail to load Executable dependency with incorrect path", () => { + expect.assertions(4); + const def: DependencyDefinition = { + name: "Node", + program: "node", + type: DependencyType.Executable, + }; + const options: DependencyOptions = { + path: "/this/is/not/going/to/work", + }; + const dependency = new ExecutableDependency(def, options); + + return dependency.load().catch(error => { + expect(error.message).toMatch( + 'Dependency "Node" is required and not installed.' + ); + expect(error.message).toMatch(`spawn ${options.path} ENOENT`); + expect(dependency.isInstalled).toBe(false); + expect(dependency.errors).toHaveLength(1); + }); }); }); -describe("successfully loaded Executable dependency", () => { +describe("successfully load Executable dependency", () => { describe("Load", () => { test("should successfully load Executable dependency", async () => { expect.assertions(3); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -43,7 +68,7 @@ describe("successfully loaded Executable dependency", () => { test("should successfully run command for Executable dependency", async () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -61,7 +86,7 @@ describe("successfully loaded Executable dependency", () => { describe("Run", () => { test("should return stdout", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -82,7 +107,7 @@ describe("successfully loaded Executable dependency", () => { test("should return stderr", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -103,7 +128,7 @@ describe("successfully loaded Executable dependency", () => { test("should return exit code", () => { expect.assertions(3); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -125,7 +150,7 @@ describe("successfully loaded Executable dependency", () => { test("should accept stdin parameter", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -151,7 +176,7 @@ describe("successfully loaded Executable dependency", () => { test("should only load once", async () => { expect.assertions(5); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", program: "node", type: DependencyType.Executable, @@ -179,7 +204,7 @@ describe("successfully loaded Executable dependency", () => { describe("Parse Version", () => { test("should successfully parse version with function", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: (text: string) => { const matches = text.match(/v(\d+.\d+.\d+)/); @@ -198,7 +223,7 @@ describe("successfully loaded Executable dependency", () => { }); test("should successfully parse version with string pattern", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: "v(\\d+.\\d+.\\d+)", program: "node", @@ -214,7 +239,7 @@ describe("successfully loaded Executable dependency", () => { }); test("should successfully parse version with RegExp pattern", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: /v(\d+\.\d+\.\d+)/, program: "node", @@ -231,7 +256,7 @@ describe("successfully loaded Executable dependency", () => { test("should successfully parse version with array of string patterns", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: ["invalid", "v(\\d+.\\d+.\\d+)"], program: "node", @@ -247,7 +272,7 @@ describe("successfully loaded Executable dependency", () => { }); test("should successfully parse version with array of RegExp patterns", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: [/invalid/, /v(\d+\.\d+\.\d+)/], program: "node", @@ -264,7 +289,7 @@ describe("successfully loaded Executable dependency", () => { test("should successfully parse partial (major.minor) version with RegExp pattern", () => { expect.assertions(2); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: /v(\d+\.\d+)/, program: "node", @@ -281,7 +306,7 @@ describe("successfully loaded Executable dependency", () => { test("should fail to parse version from text without numbers with RegExp pattern", () => { expect.assertions(3); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "Node", parseVersion: /v/, program: "node", @@ -300,7 +325,7 @@ describe("successfully loaded Executable dependency", () => { test("should successfully parse version and return first valid version from array of patterns", () => { expect.assertions(14); - const options1: DependencyOptions = { + const options1: DependencyDefinition = { name: "Fake Program 1", parseVersion: ["invalid", "v(\\d+.\\d+.\\d+)", "v(\\d+)"], program: "node", @@ -308,7 +333,7 @@ describe("successfully loaded Executable dependency", () => { versionArgs: ["-e", "console.log('v1.2.3')"], }; const dependency1 = new ExecutableDependency(options1); - const options2: DependencyOptions = { + const options2: DependencyDefinition = { name: "Fake Program 2", parseVersion: ["invalid", "v(\\d+)", "v(\\d+.\\d+.\\d+)"], program: "node", diff --git a/test/DependencyManager/NodeDependency.spec.ts b/test/DependencyManager/NodeDependency.spec.ts index 9c51f535..7c369d93 100644 --- a/test/DependencyManager/NodeDependency.spec.ts +++ b/test/DependencyManager/NodeDependency.spec.ts @@ -1,12 +1,12 @@ import { NodeDependency, DependencyType, - DependencyOptions, + DependencyDefinition, } from "../../src/DependencyManager"; test("should fail to load Node dependency", async () => { expect.assertions(5); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "NotFound", package: "notfound", type: DependencyType.Node, @@ -30,7 +30,7 @@ test("should fail to load Node dependency", async () => { describe("successfully loaded local Node dependency", () => { test("should successfully load local Node dependency", async () => { expect.assertions(4); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "FakeDep", package: "fakedep", type: DependencyType.Node, @@ -49,7 +49,7 @@ describe("successfully loaded local Node dependency", () => { describe("successfully loaded global Node dependency", () => { test("should successfully load global Node dependency", () => { expect.assertions(4); - const options: DependencyOptions = { + const options: DependencyDefinition = { name: "FakeDep", package: "global-fakedep", type: DependencyType.Node, diff --git a/test/beautifier/dependency.spec.ts b/test/beautifier/dependency.spec.ts index 633f7af3..ec14466c 100644 --- a/test/beautifier/dependency.spec.ts +++ b/test/beautifier/dependency.spec.ts @@ -2,10 +2,15 @@ import { Unibeautify, Language, Beautifier, - DependencyOptions, + DependencyDefinition, DependencyType, + DependencyManager, } from "../../src/"; +beforeEach(() => { + DependencyManager.clearRegistry(); +}); + test("should throw Error when dependency type is unknown", () => { const unibeautify = new Unibeautify(); const lang: Language = { @@ -52,7 +57,7 @@ describe("Node", () => { unibeautify.loadLanguage(lang); const beautifierResult = "Testing Result"; - const dependency: DependencyOptions = { + const dependency: DependencyDefinition = { name: "Fakedep", package: "fake", type: DependencyType.Node, @@ -96,7 +101,7 @@ describe("Executable", () => { unibeautify.loadLanguage(lang); const beautifierResult = "Testing Result"; - const dependency: DependencyOptions = { + const dependency: DependencyDefinition = { name: "Fake Program", parseVersion: text => "", program: "fakeprogram",