Skip to content

Commit

Permalink
fix: freeze the CaseFormat class and its class constants
Browse files Browse the repository at this point in the history
  • Loading branch information
Haixing-Hu committed Nov 30, 2023
1 parent 78d8784 commit 34c8656
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 2 deletions.
45 changes: 43 additions & 2 deletions src/case-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
import firstCharOnlyToUpper from './first-char-only-to-upper';
import findFirst from './find-first';
import firstCharOnlyToUpper from './impl/first-char-only-to-upper';
import findFirst from './impl/find-first';

/**
* A class that represents case formats.
Expand Down Expand Up @@ -133,6 +133,39 @@ class CaseFormat {
];
}

/**
* Returns the case format constant of the specified name.
*
* @param {String|CaseFormat} name
* the name of the case format constant, or a `CaseFormat` instance. The
* name is compared case-insensitively and the characters '-' and '_' are
* treated as the same.
* @return {CaseFormat}
* the case format constant of the specified name, or the specified
* `CaseFormat` instance if the argument `name` is a `CaseFormat` instance.
* @throws {TypeError}
* if the argument `name` is not a string nor a `CaseFormat` instance.
* @throws {Error}
* if there is no case format constant of the specified name.
*/
static of(name) {
if (name instanceof CaseFormat) {
return name;
}
if (typeof name !== 'string') {
throw new TypeError('The argument of `CaseFormat.of()` must be a string or a `CaseFormat` instance.');
}
const normalizedName = name.replace(/_/g, '-').toLowerCase();
const values = CaseFormat.values();
for (let i = 0; i < values.length; ++i) {
const value = values[i];
if (value.name.toLowerCase() === normalizedName) {
return value;
}
}
throw new Error(`Unknown case format: '${name}'.`);
}

/**
* Constructor a {@link CaseFormat} instance.
*
Expand Down Expand Up @@ -214,4 +247,12 @@ class CaseFormat {
}
}

// freeze the constants and the class
Object.freeze(CaseFormat.LOWER_HYPHEN);
Object.freeze(CaseFormat.LOWER_UNDERSCORE);
Object.freeze(CaseFormat.LOWER_CAMEL);
Object.freeze(CaseFormat.UPPER_CAMEL);
Object.freeze(CaseFormat.UPPER_UNDERSCORE);
Object.freeze(CaseFormat);

export default CaseFormat;
147 changes: 147 additions & 0 deletions test/case-format.immutable.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2022 - 2023.
// Haixing Hu, Qubit Co. Ltd.
//
// All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
import {
LOWER_HYPHEN,
LOWER_UNDERSCORE,
LOWER_CAMEL,
UPPER_CAMEL,
UPPER_UNDERSCORE,
CaseFormat,
} from '../src';

/**
* Unit tests of the immutability of the {@link CaseFormat} class.
*
* @author Haixing Hu
*/
describe('Test the immutability of the CaseFormat class', () => {
test('Test the immutability of CaseFormat.LOWER_HYPHEN', () => {
expect(() => {
LOWER_HYPHEN.name = 'xxx';
}).toThrow(Error);
expect(() => {
LOWER_HYPHEN.wordBoundaryFilter = null;
}).toThrow(Error);
expect(() => {
LOWER_HYPHEN.wordSeparator = 'xx';
}).toThrow(Error);
expect(() => {
LOWER_HYPHEN.wordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_HYPHEN.firstWordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_HYPHEN.quickOptimizer = null;
}).toThrow(Error);
});
test('Test the immutability of CaseFormat.LOWER_UNDERSCORE', () => {
expect(() => {
LOWER_UNDERSCORE.name = 'xxx';
}).toThrow(Error);
expect(() => {
LOWER_UNDERSCORE.wordBoundaryFilter = null;
}).toThrow(Error);
expect(() => {
LOWER_UNDERSCORE.wordSeparator = 'xx';
}).toThrow(Error);
expect(() => {
LOWER_UNDERSCORE.wordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_UNDERSCORE.firstWordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_UNDERSCORE.quickOptimizer = null;
}).toThrow(Error);
});
test('Test the immutability of CaseFormat.LOWER_CAMEL', () => {
expect(() => {
LOWER_CAMEL.name = 'xxx';
}).toThrow(Error);
expect(() => {
LOWER_CAMEL.wordBoundaryFilter = null;
}).toThrow(Error);
expect(() => {
LOWER_CAMEL.wordSeparator = 'xx';
}).toThrow(Error);
expect(() => {
LOWER_CAMEL.wordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_CAMEL.firstWordNormalizer = null;
}).toThrow(Error);
expect(() => {
LOWER_CAMEL.quickOptimizer = null;
}).toThrow(Error);
});
test('Test the immutability of CaseFormat.UPPER_CAMEL', () => {
expect(() => {
UPPER_CAMEL.name = 'xxx';
}).toThrow(Error);
expect(() => {
UPPER_CAMEL.wordBoundaryFilter = null;
}).toThrow(Error);
expect(() => {
UPPER_CAMEL.wordSeparator = 'xx';
}).toThrow(Error);
expect(() => {
UPPER_CAMEL.wordNormalizer = null;
}).toThrow(Error);
expect(() => {
UPPER_CAMEL.firstWordNormalizer = null;
}).toThrow(Error);
expect(() => {
UPPER_CAMEL.quickOptimizer = null;
}).toThrow(Error);
});
test('Test the immutability of CaseFormat.UPPER_UNDERSCORE', () => {
expect(() => {
UPPER_UNDERSCORE.name = 'xxx';
}).toThrow(Error);
expect(() => {
UPPER_UNDERSCORE.wordBoundaryFilter = null;
}).toThrow(Error);
expect(() => {
UPPER_UNDERSCORE.wordSeparator = 'xx';
}).toThrow(Error);
expect(() => {
UPPER_UNDERSCORE.wordNormalizer = null;
}).toThrow(Error);
expect(() => {
UPPER_UNDERSCORE.firstWordNormalizer = null;
}).toThrow(Error);
expect(() => {
UPPER_UNDERSCORE.quickOptimizer = null;
}).toThrow(Error);
});
test('Test the immutability of CaseFormat class', () => {
expect(() => {
CaseFormat.LOWER_HYPHEN = 'xxx';
}).toThrow(Error);
expect(() => {
CaseFormat.LOWER_UNDERSCORE = null;
}).toThrow(Error);
expect(() => {
CaseFormat.LOWER_CAMEL = 'xx';
}).toThrow(Error);
expect(() => {
CaseFormat.UPPER_CAMEL = null;
}).toThrow(Error);
expect(() => {
CaseFormat.UPPER_UNDERSCORE = null;
}).toThrow(Error);
expect(() => {
CaseFormat.values = null;
}).toThrow(Error);
expect(() => {
CaseFormat.of = null;
}).toThrow(Error);
});
});
79 changes: 79 additions & 0 deletions test/case-format.of.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2022 - 2023.
// Haixing Hu, Qubit Co. Ltd.
//
// All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
import {
LOWER_HYPHEN,
LOWER_UNDERSCORE,
LOWER_CAMEL,
UPPER_CAMEL,
UPPER_UNDERSCORE,
CaseFormat,
} from '../src';

/**
* Unit tests of the {@link CaseFormat#of()} function.
*
* @author Haixing Hu
*/
describe('Test the CaseFormat.of()', () => {
test('Test CaseFormat.of(), with CaseFormat instances', () => {
expect(CaseFormat.of(CaseFormat.LOWER_HYPHEN)).toBe(LOWER_HYPHEN);
expect(CaseFormat.of(CaseFormat.LOWER_UNDERSCORE)).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of(CaseFormat.LOWER_CAMEL)).toBe(LOWER_CAMEL);
expect(CaseFormat.of(CaseFormat.UPPER_CAMEL)).toBe(UPPER_CAMEL);
expect(CaseFormat.of(CaseFormat.UPPER_UNDERSCORE)).toBe(UPPER_UNDERSCORE);
});
test('Test CaseFormat.of(), with a argument of invalid type', () => {
expect(() => CaseFormat.of(undefined)).toThrow(TypeError);
expect(() => CaseFormat.of(null)).toThrow(TypeError);
expect(() => CaseFormat.of(123)).toThrow(TypeError);
});
test('Test CaseFormat.of(), with a argument of invalid name', () => {
expect(() => CaseFormat.of('xxx')).toThrow(Error);
});
test('Test CaseFormat.of(), with correct name of LOWER_HYPHEN', () => {
expect(CaseFormat.of('lower-hyphen')).toBe(LOWER_HYPHEN);
expect(CaseFormat.of('lower_hyphen')).toBe(LOWER_HYPHEN);
expect(CaseFormat.of('Lower-Hyphen')).toBe(LOWER_HYPHEN);
expect(CaseFormat.of('Lower_Hyphen')).toBe(LOWER_HYPHEN);
expect(CaseFormat.of('LOWER-HYPHEN')).toBe(LOWER_HYPHEN);
expect(CaseFormat.of('LOWER_HYPHEN')).toBe(LOWER_HYPHEN);
});
test('Test CaseFormat.of(), with correct name of LOWER_UNDERSCORE', () => {
expect(CaseFormat.of('lower-underscore')).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of('lower_underscore')).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of('Lower-Underscore')).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of('Lower_Underscore')).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of('LOWER-UNDERSCORE')).toBe(LOWER_UNDERSCORE);
expect(CaseFormat.of('LOWER_UNDERSCORE')).toBe(LOWER_UNDERSCORE);
});
test('Test CaseFormat.of(), with correct name of LOWER_CAMEL', () => {
expect(CaseFormat.of('lower-camel')).toBe(LOWER_CAMEL);
expect(CaseFormat.of('lower_camel')).toBe(LOWER_CAMEL);
expect(CaseFormat.of('Lower-Camel')).toBe(LOWER_CAMEL);
expect(CaseFormat.of('Lower_Camel')).toBe(LOWER_CAMEL);
expect(CaseFormat.of('LOWER-CAMEL')).toBe(LOWER_CAMEL);
expect(CaseFormat.of('LOWER_CAMEL')).toBe(LOWER_CAMEL);
});
test('Test CaseFormat.of(), with correct name of UPPER_CAMEL', () => {
expect(CaseFormat.of('upper-camel')).toBe(UPPER_CAMEL);
expect(CaseFormat.of('upper_camel')).toBe(UPPER_CAMEL);
expect(CaseFormat.of('Upper-Camel')).toBe(UPPER_CAMEL);
expect(CaseFormat.of('Upper_Camel')).toBe(UPPER_CAMEL);
expect(CaseFormat.of('UPPER-CAMEL')).toBe(UPPER_CAMEL);
expect(CaseFormat.of('UPPER_CAMEL')).toBe(UPPER_CAMEL);
});
test('Test CaseFormat.of(), with correct name of UPPER_UNDERSCORE', () => {
expect(CaseFormat.of('upper-underscore')).toBe(UPPER_UNDERSCORE);
expect(CaseFormat.of('upper_underscore')).toBe(UPPER_UNDERSCORE);
expect(CaseFormat.of('Upper-Underscore')).toBe(UPPER_UNDERSCORE);
expect(CaseFormat.of('Upper_Underscore')).toBe(UPPER_UNDERSCORE);
expect(CaseFormat.of('UPPER-UNDERSCORE')).toBe(UPPER_UNDERSCORE);
expect(CaseFormat.of('UPPER_UNDERSCORE')).toBe(UPPER_UNDERSCORE);
});
});

0 comments on commit 34c8656

Please sign in to comment.