From 58add4329989c77d2b1d9963cac41f3354ee82bd Mon Sep 17 00:00:00 2001 From: Stanislav Lvovsky <stanislav.lvovsky@sap.com> Date: Wed, 10 Jun 2020 11:17:05 +0300 Subject: [PATCH] Types (#300) * support multiple types * Update package.json * Update .nycrc.json * add helper method to filter.ts * Update .nycrc.json * cr fixes * update foodq --- backend/.nycrc.json | 6 ++-- backend/package.json | 2 +- backend/src/filter.ts | 28 +++++++++++++----- backend/src/vscode-youi-events.ts | 2 +- backend/src/yeomanui.ts | 10 +++---- backend/tests/filter.spec.ts | 19 +++++++++---- backend/tests/vscode-youi-events.spec.ts | 4 +-- backend/tests/yeomanui.spec.ts | 36 ++++++++++++------------ generator-foodq/package.json | 5 +++- 9 files changed, 68 insertions(+), 44 deletions(-) diff --git a/backend/.nycrc.json b/backend/.nycrc.json index ce200a9df..608987bff 100644 --- a/backend/.nycrc.json +++ b/backend/.nycrc.json @@ -8,8 +8,8 @@ "temp-dir": "./reports/.nyc_output", "report-dir": "./reports/coverage", "check-coverage": true, - "branches": 79, + "branches": 78.9, "lines": 85, - "functions": 78, - "statements": 85 + "functions": 78.8, + "statements": 84.6 } diff --git a/backend/package.json b/backend/package.json index 4cd6e34e4..257c69950 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "yeoman-ui", - "version": "1.0.13", + "version": "1.0.14", "displayName": "Application Wizard", "publisher": "SAPOS", "author": { diff --git a/backend/src/filter.ts b/backend/src/filter.ts index 0926837bc..b7fc081e4 100644 --- a/backend/src/filter.ts +++ b/backend/src/filter.ts @@ -2,8 +2,7 @@ import * as _ from "lodash"; export enum GeneratorType { project = "project", - module = "module", - all = "all" + module = "module" } function getCategories(filterObject?: any): string[] { @@ -20,17 +19,32 @@ function getCategories(filterObject?: any): string[] { return []; } -function getType(filterObject?: any): GeneratorType { - return _.get(filterObject, "type", GeneratorType.all); +function getTypes(filterObject?: any): string[] { + let types: string[] = []; + const objectTypes: any = _.get(filterObject, "types", _.get(filterObject, "type")); + if (_.isString(objectTypes)) { + types.push(objectTypes); + } else if (_.isArray(objectTypes)) { + // leave only string values + types = _.filter(objectTypes, type => { + return _.isString(type); + }); + } + + return _.compact(_.map(types, _.trim)); } export class GeneratorFilter { public static create(filterObject?: any) { const categories: string[] = getCategories(filterObject); - const type: GeneratorType = getType(filterObject); + const types: string[] = getTypes(filterObject); + + return new GeneratorFilter(types, categories); + } - return new GeneratorFilter(type, categories); + public static hasIntersection(array1: string[], array2: string[]) { + return (_.isEmpty(array1) || !_.isEmpty(_.intersection(array1, array2))) } - constructor(public readonly type: GeneratorType, public readonly categories: string[]) {} + constructor(public readonly types: string[], public readonly categories: string[]) {} } diff --git a/backend/src/vscode-youi-events.ts b/backend/src/vscode-youi-events.ts index 43ea1717c..7194ed554 100644 --- a/backend/src/vscode-youi-events.ts +++ b/backend/src/vscode-youi-events.ts @@ -59,7 +59,7 @@ export class VSCodeYouiEvents implements YouiEvents { const targetFolderUri: vscode.Uri = vscode.Uri.file(targetFolderPath); - if (this.genFilter.type !== GeneratorType.module) { + if (_.indexOf(this.genFilter.types, GeneratorType.module) === -1) { const workspacePath = _.get(vscode, "workspace.workspaceFolders[0].uri.fsPath"); // 1. target workspace folder should not already contain target generator folder const foundInWorkspace = _.find(vscode.workspace.workspaceFolders, (wsFolder: vscode.WorkspaceFolder) => { diff --git a/backend/src/yeomanui.ts b/backend/src/yeomanui.ts index 88e2a093a..693d9b3ba 100644 --- a/backend/src/yeomanui.ts +++ b/backend/src/yeomanui.ts @@ -14,7 +14,7 @@ import { YouiLog } from "./youi-log"; import { YouiEvents } from "./youi-events"; import { IRpc } from "@sap-devx/webview-rpc/out.ext/rpc-common"; import Generator = require("yeoman-generator"); -import { GeneratorType, GeneratorFilter } from "./filter"; +import { GeneratorFilter, GeneratorType } from "./filter"; import { IChildLogger } from "@vscode-logging/logger"; import {IPrompt} from "@sap-devx/yeoman-ui-types"; @@ -375,7 +375,7 @@ export class YeomanUI { const questions: any[] = []; - if (genFilter.type === GeneratorType.project) { + if (_.indexOf(genFilter.types, GeneratorType.project) > 0) { const defaultPath = this.getCwd(); const targetFolderQuestion: any = { type: "input", @@ -429,9 +429,9 @@ export class YeomanUI { } const genFilter: GeneratorFilter = GeneratorFilter.create(_.get(packageJson, ["generator-filter"])); - const typeEqual: boolean = (filter.type === GeneratorType.all || filter.type === genFilter.type); - const categoriesHasIntersection: boolean = (_.isEmpty(filter.categories) || !_.isEmpty(_.intersection(filter.categories, genFilter.categories))); - if (typeEqual && categoriesHasIntersection) { + const typesHasIntersection: boolean = GeneratorFilter.hasIntersection(filter.types, genFilter.types); + const categoriesHasIntersection: boolean = GeneratorFilter.hasIntersection(filter.categories, genFilter.categories); + if (typesHasIntersection && categoriesHasIntersection) { return this.createGeneratorChoice(genName, genPackagePath, packageJson); } diff --git a/backend/tests/filter.spec.ts b/backend/tests/filter.spec.ts index 8407de1af..fe7c83e3e 100644 --- a/backend/tests/filter.spec.ts +++ b/backend/tests/filter.spec.ts @@ -1,7 +1,7 @@ import * as mocha from "mocha"; import { expect } from "chai"; -import {GeneratorFilter, GeneratorType} from "../src/filter"; +import {GeneratorFilter} from "../src/filter"; describe('filter unit test', () => { it('categories property is not of array type', () => { @@ -18,28 +18,35 @@ describe('filter unit test', () => { const testCategories: string[] = ["test1", "test2"]; const genFilter: GeneratorFilter = GeneratorFilter.create({type: "test123", categories: testCategories}); // tslint:disable-next-line: no-unused-expression - expect(genFilter.type).to.be.equal("test123"); + expect(genFilter.types).to.contain("test123"); expect(genFilter.categories).to.be.deep.equal(testCategories); }); it('filter obj is undefined', () => { const genFilter: GeneratorFilter = GeneratorFilter.create(undefined); // tslint:disable-next-line: no-unused-expression - expect(genFilter.type).to.be.equal(GeneratorType.all); + expect(genFilter.types).to.be.empty; + expect(genFilter.categories).to.be.deep.equal([]); + }); + + it('filter type is neither array nor string', () => { + const genFilter: GeneratorFilter = GeneratorFilter.create({types: {}}); + // tslint:disable-next-line: no-unused-expression + expect(genFilter.types).to.be.empty; expect(genFilter.categories).to.be.deep.equal([]); }); it('type property is project and category property has strings in array ', () => { const testCategories: string[] = ["test1", "test2"]; const genFilter: GeneratorFilter = GeneratorFilter.create({type: "project", categories: testCategories}); - expect(genFilter.type).to.be.equal(GeneratorType.project); + expect(genFilter.types).to.contain("project"); expect(genFilter.categories).to.be.deep.equal(testCategories); }); it('type property is module and category property has strings in array ', () => { const testCategories: string[] = ["test1", "test2"]; - const genFilter: GeneratorFilter = GeneratorFilter.create({type: "module", categories: testCategories}); - expect(genFilter.type).to.be.equal(GeneratorType.module); + const genFilter: GeneratorFilter = GeneratorFilter.create({types: [" module"], categories: testCategories}); + expect(genFilter.types).to.contain("module"); expect(genFilter.categories).to.be.deep.equal(testCategories); }); }); \ No newline at end of file diff --git a/backend/tests/vscode-youi-events.spec.ts b/backend/tests/vscode-youi-events.spec.ts index 2a1b17859..1bafc02ec 100644 --- a/backend/tests/vscode-youi-events.spec.ts +++ b/backend/tests/vscode-youi-events.spec.ts @@ -3,7 +3,7 @@ import { expect } from "chai"; import * as sinon from "sinon"; import * as _ from "lodash"; import * as vscode from "vscode"; -import { GeneratorFilter, GeneratorType } from '../src/filter'; +import { GeneratorFilter } from '../src/filter'; import { VSCodeYouiEvents } from "../src/vscode-youi-events"; @@ -106,7 +106,7 @@ describe('vscode-youi-events unit test', () => { }); it("generator filter type is module", () => { - const genFilter = GeneratorFilter.create({type: GeneratorType.module}); + const genFilter = GeneratorFilter.create({type: ["module"]}); const events = new VSCodeYouiEvents(undefined, undefined, genFilter); eventsMock = sandbox.mock(events); eventsMock.expects("doClose"); diff --git a/backend/tests/yeomanui.spec.ts b/backend/tests/yeomanui.spec.ts index 795fcb0ec..a202090f5 100644 --- a/backend/tests/yeomanui.spec.ts +++ b/backend/tests/yeomanui.spec.ts @@ -11,7 +11,7 @@ import * as yeomanEnv from "yeoman-environment"; import { YouiLog } from "../src/youi-log"; import { YouiEvents } from '../src/youi-events'; import { IMethod, IPromiseCallbacks, IRpc } from "@sap-devx/webview-rpc/out.ext/rpc-common"; -import { GeneratorType, GeneratorFilter } from "../src/filter"; +import { GeneratorFilter } from "../src/filter"; import { IChildLogger } from "@vscode-logging/logger"; import * as os from "os"; import { fail } from "assert"; @@ -233,13 +233,13 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test4Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project"}, "description": "test4Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test5Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test5Description"}`); - const genFilter: GeneratorFilter = GeneratorFilter.create({type: GeneratorType.project}); + const genFilter: GeneratorFilter = GeneratorFilter.create({type: "project"}); yeomanUi["uiOptions"] = {genFilter, messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); - expect(result.questions[1].choices).to.have.lengthOf(2); - const test1Choice = result.questions[1].choices[0]; - const test2Choice = result.questions[1].choices[1]; + expect(result.questions[0].choices).to.have.lengthOf(2); + const test1Choice = result.questions[0].choices[0]; + const test2Choice = result.questions[0].choices[1]; expect(test1Choice.name).to.be.equal("Test1"); expect(test1Choice.description).to.be.equal("test1Description"); expect(test2Choice.name).to.be.equal("Test4"); @@ -272,7 +272,7 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test4Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project"}, "description": "test4Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test5Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test5Description"}`); - const genFilter = GeneratorFilter.create({type: GeneratorType.module}); + const genFilter = GeneratorFilter.create({type: "module"}); yeomanUi["uiOptions"] = {genFilter, messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); @@ -312,7 +312,7 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test5Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test5Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test6Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "all"}}`); - yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: GeneratorType.all}), messages: {}}; + yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: []}), messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); expect(result.questions[0].choices).to.have.lengthOf(6); @@ -344,7 +344,7 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test4Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project"}, "description": "test4Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test5Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test5Description"}`); - yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: GeneratorType.all}), messages: {}}; + yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: []}), messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); expect(result.questions[0].choices).to.have.lengthOf(3); @@ -360,11 +360,11 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test1Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project123"}, "description": "test4Description"}`); - yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: GeneratorType.project}), messages: {}}; + yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: "project"}), messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); // tslint:disable-next-line: no-unused-expression - expect(result.questions[1].choices).to.be.empty; + expect(result.questions[0].choices).to.be.empty; }); it("get generators with type project and categories cat1 and cat2", async () => { @@ -387,20 +387,20 @@ describe('yeomanui unit test', () => { }); envMock.expects("getGeneratorNames").returns(["test1", "test2", "test3", "test4", "test5"]); - fsExtraMock.expects("readFile").withExactArgs(path.join("test1Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project", "categories": ["cat2"]}, "description": "test1Description"}`); + fsExtraMock.expects("readFile").withExactArgs(path.join("test1Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": ["project"], "categories": ["cat2"]}, "description": "test1Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test2Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project", "categories": ["cat2", "cat1"]}}`); - fsExtraMock.expects("readFile").withExactArgs(path.join("test3Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "module"}}`); + fsExtraMock.expects("readFile").withExactArgs(path.join("test3Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": ["module"]}}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test4Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "project", "categories": ["cat1"]}, "description": "test4Description"}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test5Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test5Description"}`); - const genFilter: GeneratorFilter = GeneratorFilter.create({type: GeneratorType.project, categories: ["cat1", "cat2"]}); + const genFilter: GeneratorFilter = GeneratorFilter.create({type: ["project"], categories: ["cat1", "cat2"]}); yeomanUi["uiOptions"].genFilter = genFilter; const result = await yeomanUi["getGeneratorsPrompt"](); - expect(result.questions[1].choices).to.have.lengthOf(3); - const test1Choice = result.questions[1].choices[0]; - const test2Choice = result.questions[1].choices[1]; - const test3Choice = result.questions[1].choices[2]; + expect(result.questions[0].choices).to.have.lengthOf(3); + const test1Choice = result.questions[0].choices[0]; + const test2Choice = result.questions[0].choices[1]; + const test3Choice = result.questions[0].choices[2]; expect(test1Choice.name).to.be.equal("Test1"); expect(test2Choice.name).to.be.equal("Test2"); expect(test3Choice.name).to.be.equal("Test4"); @@ -424,7 +424,7 @@ describe('yeomanui unit test', () => { fsExtraMock.expects("readFile").withExactArgs(path.join("test2Path", PACKAGE_JSON), UTF8).resolves(`{"generator-filter": {"type": "module"}}`); fsExtraMock.expects("readFile").withExactArgs(path.join("test3Path", PACKAGE_JSON), UTF8).resolves(`{"description": "test3Description", "displayName": "3rd - Test"}`); - yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: GeneratorType.all}), messages: {}}; + yeomanUi["uiOptions"] = {genFilter: GeneratorFilter.create({type: undefined}), messages: {}}; const result = await yeomanUi["getGeneratorsPrompt"](); const choices = result.questions[0].choices; diff --git a/generator-foodq/package.json b/generator-foodq/package.json index 6c83f5d87..d2ef207d7 100644 --- a/generator-foodq/package.json +++ b/generator-foodq/package.json @@ -29,6 +29,9 @@ "@sap-devx/yeoman-ui-types": "0.0.1" }, "generator-filter": { - "type": "project" + "types": [ + "foodq", + "project" + ] } }