Skip to content

Commit

Permalink
Types (#300)
Browse files Browse the repository at this point in the history
* support multiple types

* Update package.json

* Update .nycrc.json

* add helper method to filter.ts

* Update .nycrc.json

* cr fixes

* update foodq
  • Loading branch information
slavik-lvovsky authored Jun 10, 2020
1 parent 3cb5f87 commit 58add43
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 44 deletions.
6 changes: 3 additions & 3 deletions backend/.nycrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yeoman-ui",
"version": "1.0.13",
"version": "1.0.14",
"displayName": "Application Wizard",
"publisher": "SAPOS",
"author": {
Expand Down
28 changes: 21 additions & 7 deletions backend/src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import * as _ from "lodash";

export enum GeneratorType {
project = "project",
module = "module",
all = "all"
module = "module"
}

function getCategories(filterObject?: any): string[] {
Expand All @@ -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[]) {}
}
2 changes: 1 addition & 1 deletion backend/src/vscode-youi-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
10 changes: 5 additions & 5 deletions backend/src/yeomanui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
}

Expand Down
19 changes: 13 additions & 6 deletions backend/tests/filter.spec.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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);
});
});
4 changes: 2 additions & 2 deletions backend/tests/vscode-youi-events.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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");
Expand Down
36 changes: 18 additions & 18 deletions backend/tests/yeomanui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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"]();

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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 () => {
Expand All @@ -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");
Expand All @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion generator-foodq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"@sap-devx/yeoman-ui-types": "0.0.1"
},
"generator-filter": {
"type": "project"
"types": [
"foodq",
"project"
]
}
}

0 comments on commit 58add43

Please sign in to comment.