Skip to content

Commit

Permalink
test: isValidKey
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanhaticus committed Nov 6, 2024
1 parent 5aad0b7 commit c462506
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 6 deletions.
105 changes: 105 additions & 0 deletions __tests__/utils/isValidKey.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Chance } from 'chance';
import { isValidKey } from '../../src/utils/isValidKey';
import { firstOnlyCharacters, middleOnlyCharacters, reservedCharacters } from '../../src/constants/characterSets';

describe('`isValidKey`', () => {
let chance: Chance.Chance;

beforeEach(() => {
chance = new Chance();
});

it('should throw errors that correctly reference the decorator name and key', () => {
const decoratorName = chance.string();
const key = chance.integer();

try {
isValidKey(decoratorName, key);
} catch (error) {
expect(error.message).toContain(
`@${decoratorName} can only be applied to specific keys. Expected key ${key.toString()}`,
);
}
});

it('should throw an error if the key is not a string', () => {
const key = chance.pickone([Symbol(), chance.integer()]);

try {
isValidKey('some-decorator', key);
} catch (error) {
expect(error.message).toContain(
`Expected key ${key.toString()} to be of type string, but received ${typeof key}.`,
);
}
});

it('should throw an error if the key is an empty string', () => {
const key = '';

try {
isValidKey('some-decorator', key);
} catch (error) {
expect(error.message).toContain('Expected key to be non-empty.');
}
});

it('should throw an error if the key contains reserved characters', () => {
const key = chance.pickone([...reservedCharacters]);

try {
isValidKey('some-decorator', key);
}
catch (error) {
expect(error.message).toContain(
`Expected key ${key} to not contain any reserved characters, but found ${key}.`,
);
}
});

it('should throw an error if the key contains first only characters after the first character', () => {
const firstOnlyCharacter = chance.pickone([...firstOnlyCharacters]);
const key = `${chance.guid()}${firstOnlyCharacter}`;

try {
isValidKey('some-decorator', key);
} catch (error) {
expect(error.message).toContain(
`Expected key ${key} to not contain the characters ${firstOnlyCharacter}, except as the first character.`,
);
}
});

it('should allow first only characters as the first character', () => {
const firstOnlyCharacter = chance.pickone([...firstOnlyCharacters]);
const key = `${firstOnlyCharacter}${chance.guid()}`;

expect(isValidKey('some-decorator', key)).toBe(true);
});

it('should throw an error if the key contains middle only characters as the first or last character', () => {
const middleOnlyCharacter = chance.pickone([...middleOnlyCharacters]);
const key = `${middleOnlyCharacter}${chance.guid()}${middleOnlyCharacter}`;

try {
isValidKey('some-decorator', key);
} catch (error) {
expect(error.message).toContain(
`Expected key ${key} to not contain the characters ${middleOnlyCharacter}, ${middleOnlyCharacter} as the first or last character.`,
);
}
});

it('should allow middle only characters in the middle of the key', () => {
const middleOnlyCharacter = chance.pickone([...middleOnlyCharacters]);
const key = `${chance.guid()}${middleOnlyCharacter}${chance.guid()}`;

expect(isValidKey('some-decorator', key)).toBe(true);
});

it('should return true if the key is valid', () => {
const key = chance.guid();

expect(isValidKey('some-decorator', key)).toBe(true);
});
});
4 changes: 2 additions & 2 deletions src/constants/characterSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export const reservedCharacters: ReadonlySet<string> = new Set([
'\u001F',
]);

export const firstCharacterOnly: ReadonlySet<string> = new Set(['\u0040']);
export const firstOnlyCharacters: ReadonlySet<string> = new Set(['\u0040']);

export const notFirstOrLastCharacter: ReadonlySet<string> = new Set([
export const middleOnlyCharacters: ReadonlySet<string> = new Set([
'\u002D',
'\u005F',
'\u0020',
Expand Down
8 changes: 4 additions & 4 deletions src/utils/isValidKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
firstCharacterOnly,
notFirstOrLastCharacter,
firstOnlyCharacters,
middleOnlyCharacters,
reservedCharacters,
} from '../constants/characterSets';

Expand Down Expand Up @@ -32,7 +32,7 @@ export const isValidKey = (
}

const firstCharacterViolations = charactersInKey.filter(
(character, index) => firstCharacterOnly.has(character) && index !== 0,
(character, index) => firstOnlyCharacters.has(character) && index !== 0,
);
if (firstCharacterViolations.length > 0) {
throw new Error(
Expand All @@ -42,7 +42,7 @@ export const isValidKey = (

const firstOrLastCharacterViolations = charactersInKey.filter(
(character, index) =>
notFirstOrLastCharacter.has(character) &&
middleOnlyCharacters.has(character) &&
(index === 0 || index === charactersInKey.length - 1),
);
if (firstOrLastCharacterViolations.length > 0) {
Expand Down

0 comments on commit c462506

Please sign in to comment.