Skip to content

Commit 33d5592

Browse files
committed
Adding changes for -ve values
1 parent e95e529 commit 33d5592

2 files changed

Lines changed: 145 additions & 3 deletions

File tree

packages/code-analyzer-core/src/config.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export type BulkSuppressionRule = {
6464
*/
6565
export type Suppressions = {
6666
disable_suppressions: boolean;
67-
bulk_suppressions: Record<string, BulkSuppressionRule[]>;
67+
bulk_suppressions?: Record<string, BulkSuppressionRule[]>;
6868
}
6969

7070
type TopLevelConfig = {
@@ -85,7 +85,7 @@ export const DEFAULT_CONFIG: TopLevelConfig = {
8585
config_root: process.cwd(),
8686
log_folder: os.tmpdir(),
8787
log_level: LogLevel.Debug,
88-
suppressions: { disable_suppressions: false, bulk_suppressions: {} }, // Suppressions enabled by default, no bulk suppressions by default
88+
suppressions: { disable_suppressions: false }, // Suppressions enabled by default, no bulk suppressions by default
8989
rules: {},
9090
engines: {},
9191
ignores: { files: [] },
@@ -287,7 +287,7 @@ export class CodeAnalyzerConfig {
287287
* Returns the bulk suppressions configuration (file paths mapped to suppression rules).
288288
*/
289289
public getBulkSuppressions(): Record<string, BulkSuppressionRule[]> {
290-
return this.config.suppressions.bulk_suppressions;
290+
return this.config.suppressions.bulk_suppressions || {};
291291
}
292292

293293
/**
@@ -465,6 +465,11 @@ function validateBulkSuppressionRule(value: unknown, fieldPath: string): BulkSup
465465
throw new Error(getMessage('InvalidBulkSuppressionRule', fieldPath, 'max_suppressed_violations must be a number or null'));
466466
}
467467

468+
// max_suppressed_violations must be non-negative if specified
469+
if (typeof rule.max_suppressed_violations === 'number' && rule.max_suppressed_violations < 0) {
470+
throw new Error(getMessage('InvalidBulkSuppressionRule', fieldPath, 'max_suppressed_violations must be a non-negative number'));
471+
}
472+
468473
// reason is optional
469474
if (rule.reason !== undefined && typeof rule.reason !== 'string') {
470475
throw new Error(getMessage('InvalidBulkSuppressionRule', fieldPath, 'reason must be a string'));

packages/code-analyzer-core/test/config.test.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,3 +642,140 @@ describe("Tests for glob pattern validation in ignores", () => {
642642
})).toThrow(getMessage('InvalidGlobPattern', 'ignores.files[2]', '**/invalid{pattern', 'unclosed brace {'));
643643
});
644644
});
645+
646+
describe("Tests for bulk suppressions configuration", () => {
647+
it("When suppressions.disable_suppressions is set correctly, config is valid", () => {
648+
const conf: CodeAnalyzerConfig = CodeAnalyzerConfig.fromYamlString(`
649+
suppressions:
650+
disable_suppressions: true
651+
`);
652+
expect(conf.getSuppressions().disable_suppressions).toEqual(true);
653+
});
654+
655+
it("When bulk suppressions are configured with valid values, config is valid", () => {
656+
const conf: CodeAnalyzerConfig = CodeAnalyzerConfig.fromYamlString(`
657+
suppressions:
658+
disable_suppressions: false
659+
"src/file.js":
660+
- rule_selector: "eslint:no-console"
661+
max_suppressed_violations: 5
662+
reason: "Legacy code"
663+
`);
664+
expect(conf.getBulkSuppressions()).toEqual({
665+
"src/file.js": [{
666+
rule_selector: "eslint:no-console",
667+
max_suppressed_violations: 5,
668+
reason: "Legacy code"
669+
}]
670+
});
671+
});
672+
673+
it("When max_suppressed_violations is null, config is valid", () => {
674+
const conf: CodeAnalyzerConfig = CodeAnalyzerConfig.fromYamlString(`
675+
suppressions:
676+
"src/file.js":
677+
- rule_selector: "eslint:no-console"
678+
max_suppressed_violations: null
679+
`);
680+
expect(conf.getBulkSuppressions()["src/file.js"][0].max_suppressed_violations).toBeNull();
681+
});
682+
683+
it("When max_suppressed_violations is 0, config is valid", () => {
684+
const conf: CodeAnalyzerConfig = CodeAnalyzerConfig.fromYamlString(`
685+
suppressions:
686+
"src/file.js":
687+
- rule_selector: "eslint:no-console"
688+
max_suppressed_violations: 0
689+
`);
690+
expect(conf.getBulkSuppressions()["src/file.js"][0].max_suppressed_violations).toEqual(0);
691+
});
692+
693+
it("When max_suppressed_violations is negative, then we throw an error", () => {
694+
expect(() => CodeAnalyzerConfig.fromYamlString(`
695+
suppressions:
696+
"src/file.js":
697+
- rule_selector: "eslint:no-console"
698+
max_suppressed_violations: -1
699+
`)).toThrow('max_suppressed_violations must be a non-negative number');
700+
});
701+
702+
it("When max_suppressed_violations is negative decimal, then we throw an error", () => {
703+
expect(() => CodeAnalyzerConfig.fromYamlString(`
704+
suppressions:
705+
"src/utils/":
706+
- rule_selector: "pmd:UnusedMethod"
707+
max_suppressed_violations: -5.5
708+
`)).toThrow('max_suppressed_violations must be a non-negative number');
709+
});
710+
711+
it("When max_suppressed_violations is a large negative number, then we throw an error", () => {
712+
expect(() => CodeAnalyzerConfig.fromObject({
713+
suppressions: {
714+
"file.js": [{
715+
rule_selector: "all",
716+
max_suppressed_violations: -9999
717+
}]
718+
}
719+
})).toThrow('max_suppressed_violations must be a non-negative number');
720+
});
721+
722+
it("When rule_selector is missing, then we throw an error", () => {
723+
expect(() => CodeAnalyzerConfig.fromYamlString(`
724+
suppressions:
725+
"src/file.js":
726+
- max_suppressed_violations: 5
727+
`)).toThrow('rule_selector is required and must be a string');
728+
});
729+
730+
it("When rule_selector is not a string, then we throw an error", () => {
731+
expect(() => CodeAnalyzerConfig.fromObject({
732+
suppressions: {
733+
"file.js": [{
734+
rule_selector: 123,
735+
max_suppressed_violations: 5
736+
}]
737+
}
738+
})).toThrow('rule_selector is required and must be a string');
739+
});
740+
741+
it("When max_suppressed_violations is not a number or null, then we throw an error", () => {
742+
expect(() => CodeAnalyzerConfig.fromObject({
743+
suppressions: {
744+
"file.js": [{
745+
rule_selector: "all",
746+
max_suppressed_violations: "invalid"
747+
}]
748+
}
749+
})).toThrow('max_suppressed_violations must be a number or null');
750+
});
751+
752+
it("When reason is not a string, then we throw an error", () => {
753+
expect(() => CodeAnalyzerConfig.fromObject({
754+
suppressions: {
755+
"file.js": [{
756+
rule_selector: "all",
757+
max_suppressed_violations: 5,
758+
reason: 123
759+
}]
760+
}
761+
})).toThrow('reason must be a string');
762+
});
763+
764+
it("When bulk suppression rule is not an object, then we throw an error", () => {
765+
expect(() => CodeAnalyzerConfig.fromObject({
766+
suppressions: {
767+
"file.js": ["invalid"]
768+
}
769+
})).toThrow('Expected an object');
770+
});
771+
772+
it("When bulk suppression value for file is not an array, then we throw an error", () => {
773+
expect(() => CodeAnalyzerConfig.fromObject({
774+
suppressions: {
775+
"file.js": {
776+
rule_selector: "all"
777+
}
778+
}
779+
})).toThrow("must be of type 'array'");
780+
});
781+
});

0 commit comments

Comments
 (0)