Implemented enum descriptor for string enums

This commit is contained in:
Kir_Antipov 2023-01-18 12:28:01 +00:00
parent e16de98226
commit 41d4de590e
2 changed files with 115 additions and 0 deletions

View file

@ -0,0 +1,68 @@
import { split } from "@/utils/string-utils";
import { ENUM_SEPARATORS, DEFAULT_ENUM_SEPARATOR } from "../enum-separators";
import { EnumDescriptor } from "./enum-descriptor";
/**
* This descriptor is used to describe a set of flags stored as a `string` value.
*
* @remarks
*
* It's super inefficient, when it comes to flags, because the whole concept
* of string flags just seems too shady to me to optimize for these scenarios.
* So, string enums are ok, but string enums with flags are not recommended.
*/
export class StringDescriptor implements EnumDescriptor<string> {
/**
* @inheritdoc
*/
get name(): "string" {
return "string";
}
/**
* @inheritdoc
*/
get defaultValue(): string {
return "";
}
/**
* @inheritdoc
*/
hasFlag(value: string, flag: string): boolean {
if (flag === this.defaultValue || flag === value) {
return true;
}
if (!value) {
return false;
}
const flags = split(value, ENUM_SEPARATORS, { trimEntries: true, removeEmptyEntries: true });
return flags.includes(flag);
}
/**
* @inheritdoc
*/
addFlag(value: string, flag: string): string {
value = this.removeFlag(value, flag);
return value ? `${value}${DEFAULT_ENUM_SEPARATOR} ${flag}` : value;
}
/**
* @inheritdoc
*/
removeFlag(value: string, flag: string): string {
if (value === this.defaultValue || flag === this.defaultValue) {
return value;
}
if (value === flag) {
return this.defaultValue;
}
const flags = split(value, ENUM_SEPARATORS, { trimEntries: true, removeEmptyEntries: true });
return flags.filter(x => x !== flag).join(DEFAULT_ENUM_SEPARATOR + " ");
}
}

View file

@ -0,0 +1,47 @@
import { StringDescriptor } from "@/utils/enum/descriptors/string-descriptor";
describe("StringDescriptor", () => {
const descriptor = new StringDescriptor();
describe("name", () => {
test("returns 'string' as name", () => {
expect(descriptor.name).toBe("string");
});
});
describe("defaultValue", () => {
test("returns '' as default value", () => {
expect(descriptor.defaultValue).toBe("");
});
});
describe("hasFlag", () => {
test("returns true if flag is set", () => {
expect(descriptor.hasFlag("value1, value2, value3", "value2")).toBe(true);
});
test("returns false if flag is not set", () => {
expect(descriptor.hasFlag("value1, value2, value3", "value4")).toBe(false);
});
});
describe("addFlag", () => {
test("adds flag to value", () => {
expect(descriptor.addFlag("value1, value2", "value3")).toBe("value1, value2, value3");
});
test("does not add flag if it is already set", () => {
expect(descriptor.addFlag("value1, value2, value3", "value3")).toBe("value1, value2, value3");
});
});
describe("removeFlag", () => {
test("removes flag from value", () => {
expect(descriptor.removeFlag("value1, value2, value3", "value2")).toBe("value1, value3");
});
test("does not remove flag if it does not exist", () => {
expect(descriptor.removeFlag("value1, value2", "value3")).toBe("value1, value2");
});
});
});