Skip to content

Commit

Permalink
feat(app): Adds negative rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Panaetius committed Jan 17, 2020
1 parent dfc8c58 commit bf4aa40
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 1 deletion.
52 changes: 52 additions & 0 deletions src/LabelMatcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ describe("LabelMatcher", () => {
expect(matcher.contains({values: ["one", "two", "three"]})).toBeFalsy();
expect(matcher.contains({values: ["one", "two", "three", "test"]})).toBeTruthy();
});
it("LabelMatcher.not should not return match if any of Github labels matches provided config labels", () => {
const labels: IGithubLabel[] = [
{name: "bug"},
{name: "feat"},
{name: "test"}
];
const matcher = new LabelMatcher(labels);
expect(matcher.not({not: ["one", "two", "three"]})).toBeTruthy();
expect(matcher.not({not: ["one", "two", "three", "test"]})).toBeFalsy();
});
it("LabelMatcher.startsWith should return match if any of Github labels matches provided config labels", () => {
const labels: IGithubLabel[] = [
{name: "bug"},
Expand All @@ -39,6 +49,27 @@ describe("LabelMatcher", () => {
expect(matcher.startsWith({startsWith: x.input})).toBe(x.result);
});
});
it("LabelMatcher.doesntStartWith shouldn't return match if any of Github labels matches provided config labels", () => {
const labels: IGithubLabel[] = [
{name: "bug"},
{name: "feat"},
{name: "test"}
];
const matcher = new LabelMatcher(labels);
const tests = [
{input: ["one", "two", "three"], result: true},
{input: ["one", "two", "three", "b"], result: false},
{input: ["one", "two", "three", "bu"], result: false},
{input: ["one", "two", "three", "bug"], result: false},
{input: ["one", "two", "t", "bug"], result: false},
{input: ["one", "two", "te", "bug"], result: false},
{input: ["one", "two", "tes", "bug"], result: false},
{input: ["one", "two", "test", "bug"], result: false}
];
tests.forEach((x) => {
expect(matcher.doesntStartWith({doesntStartWith: x.input})).toBe(x.result);
});
});
it("LabelMatcher.endsWith should return match if any of Github labels matches provided config labels", () => {
const labels: IGithubLabel[] = [
{name: "bug"},
Expand All @@ -58,6 +89,25 @@ describe("LabelMatcher", () => {
expect(matcher.endsWith({endsWith: x.input})).toBe(x.result);
});
});
it("LabelMatcher.doesntEndWith shouldn't return match if any of Github labels matches provided config labels", () => {
const labels: IGithubLabel[] = [
{name: "bug"},
{name: "feat"},
{name: "test"}
];
const matcher = new LabelMatcher(labels);
const tests = [
{input: ["one", "two", "three"], result: true},
{input: ["one", "two", "three", "b"], result: true},
{input: ["one", "two", "three", "bu"], result: true},
{input: ["one", "two", "three", "bug"], result: false},
{input: ["one", "two", "t", "bu"], result: false},
{input: ["one", "two", "st", "bu"], result: false}
];
tests.forEach((x) => {
expect(matcher.doesntEndWith({doesntEndWith: x.input})).toBe(x.result);
});
});
describe("LabelMatcher.matches should have match", () => {
it("should return true if config is completely empty", () => {
const matcher = new LabelMatcher([]);
Expand All @@ -76,6 +126,8 @@ describe("LabelMatcher", () => {
expect(matcher.matches({version: "2", invalidStatus: "failed", labelRule: {startsWith: ["b"], values: ["feat"]}})).toBeFalsy();
expect(matcher.matches({version: "2", invalidStatus: "failed", labelRule: {startsWith: ["b"], endsWith: ["g"], values: ["feat"]}})).toBeFalsy();
expect(matcher.matches({version: "2", invalidStatus: "failed", labelRule: {startsWith: ["b"], endsWith: ["g"], values: ["bug"]}})).toBeTruthy();
expect(matcher.matches({version: "2", invalidStatus: "failed", labelRule: {doesntStartWith: ["b"], doesntEndWith: ["g"], not: ["feat"]}})).toBeFalsy();
expect(matcher.matches({version: "2", invalidStatus: "failed", labelRule: {doesntStartWith: ["a"], doesntEndWith: ["b"], not: ["feat"]}})).toBeTruthy();
});
});

Expand Down
37 changes: 36 additions & 1 deletion src/LabelMatcher.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export interface IGithubConfig {
version: string;
invalidStatus: "failed" | "pending";
labelRule: ILabelEndsWithRule | ILabelStartsWithRule | ILabelEqualsRule | {};
labelRule: ILabelEndsWithRule | ILabelStartsWithRule | ILabelEqualsRule |
ILabelDoesntEndWithRule | ILabelDoesntStartWithRule | ILabelNotRule | {};
}

export interface IGithubLabel {
Expand All @@ -25,6 +26,18 @@ export interface ILabelStartsWithRule {
startsWith: string[];
}

export interface ILabelNotRule {
not: string[];
}

export interface ILabelDoesntStartWithRule {
doesntStartWith: string[];
}

export interface ILabelDoesntEndWithRule {
doesntEndWith: string[];
}

export class LabelMatcher {
constructor(private labels: IGithubLabel[]) {}

Expand All @@ -44,6 +57,22 @@ export class LabelMatcher {
});
}

public not(config: ILabelNotRule): boolean {
return !this.labels.some((x) => config.not.includes(x.name));
}

public doesntStartWith(config: ILabelDoesntStartWithRule): boolean {
return !this.labels.some((x) => {
return config.doesntStartWith.some((ruleLabel) => x.name.startsWith(ruleLabel));
});
}

public doesntEndWith(config: ILabelDoesntEndWithRule): boolean {
return !this.labels.some((x) => {
return config.doesntEndWith.some((ruleLabel) => x.name.endsWith(ruleLabel));
});
}

public matches(config: IGithubConfig): boolean {
return Object.keys(config.labelRule).every((x) => {
switch (x) {
Expand All @@ -53,6 +82,12 @@ export class LabelMatcher {
return this.startsWith(config.labelRule as ILabelStartsWithRule);
case "values":
return this.contains(config.labelRule as ILabelEqualsRule);
case "not":
return this.not(config.labelRule as ILabelNotRule);
case "doesntStartWith":
return this.doesntStartWith(config.labelRule as ILabelDoesntStartWithRule);
case "doesntEndWith":
return this.doesntEndWith(config.labelRule as ILabelDoesntEndWithRule);
default:
throw new Error(`rule ${x} not supported`);
}
Expand Down

0 comments on commit bf4aa40

Please sign in to comment.