Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e646635

Browse files
brianmcdkoskimas
authored andcommitted
Fixes Vincit#1676
1 parent 6e3fdc4 commit e646635

File tree

3 files changed

+57
-6
lines changed

3 files changed

+57
-6
lines changed

lib/utils/identifierMapping.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ function memoize(func) {
2121
// camelCase to snake_case converter that also works with non-ascii characters
2222
// This is needed especially so that aliases containing the `:` character,
2323
// objection uses internally, work.
24-
function snakeCase(str, { upperCase = false, underscoreBeforeDigits = false } = {}) {
24+
function snakeCase(
25+
str,
26+
{
27+
upperCase = false,
28+
underscoreBeforeDigits = false,
29+
underscoreBetweenUppercaseLetters = false
30+
} = {}
31+
) {
2532
if (str.length === 0) {
2633
return str;
2734
}
@@ -52,12 +59,16 @@ function snakeCase(str, { upperCase = false, underscoreBeforeDigits = false } =
5259
// Test if `char` is an upper-case character and that the character
5360
// actually has different upper and lower case versions.
5461
if (char === upperChar && upperChar !== lowerChar) {
55-
// Multiple consecutive upper case characters shouldn't add underscores.
56-
// For example "fooBAR" should be converted to "foo_bar".
57-
if (prevChar === prevUpperChar && prevUpperChar !== prevLowerChar) {
58-
out += lowerChar;
59-
} else {
62+
const prevCharacterIsUppercase =
63+
prevChar === prevUpperChar && prevUpperChar !== prevLowerChar;
64+
65+
// If underscoreBetweenUppercaseLetters is true, we always place an underscore
66+
// before consecutive uppercase letters (e.g. "fooBAR" becomes "foo_b_a_r").
67+
// Otherwise, we don't (e.g. "fooBAR" becomes "foo_bar").
68+
if (underscoreBetweenUppercaseLetters || !prevCharacterIsUppercase) {
6069
out += '_' + lowerChar;
70+
} else {
71+
out += lowerChar;
6172
}
6273
} else {
6374
out += char;

tests/unit/utils.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,35 @@ describe('utils', () => {
141141
testUnderscoreBeforeNumbers('fooBar:spamBaz:troloLolo', 'foo_bar:spam_baz:trolo_lolo');
142142
testUnderscoreBeforeNumbers('fooBar.spamBaz.troloLolo', 'foo_bar.spam_baz.trolo_lolo');
143143

144+
testUnderscoreBetweenUppercaseLetters('*', '*');
145+
146+
testUnderscoreBetweenUppercaseLetters('foo', 'foo');
147+
testUnderscoreBetweenUppercaseLetters('fooBar', 'foo_bar');
148+
testUnderscoreBetweenUppercaseLetters('foo1Bar2', 'foo1_bar2');
149+
testUnderscoreBetweenUppercaseLetters('fooBAR', 'foo_b_a_r');
150+
testUnderscoreBetweenUppercaseLetters('fooBaR', 'foo_ba_r');
151+
152+
testUnderscoreBetweenUppercaseLetters('föö', 'föö');
153+
testUnderscoreBetweenUppercaseLetters('fööBär', 'föö_bär');
154+
testUnderscoreBetweenUppercaseLetters('föö1Bär2', 'föö1_bär2');
155+
testUnderscoreBetweenUppercaseLetters('föö09Bär90', 'föö09_bär90');
156+
testUnderscoreBetweenUppercaseLetters('fööBÄR', 'föö_b_ä_r');
157+
testUnderscoreBetweenUppercaseLetters('fööBäR', 'föö_bä_r');
158+
159+
testUnderscoreBetweenUppercaseLetters('foo1bar2', 'foo1bar2');
160+
testUnderscoreBetweenUppercaseLetters('Foo', 'foo', 'foo');
161+
testUnderscoreBetweenUppercaseLetters('FooBar', 'foo_bar', 'fooBar');
162+
testUnderscoreBetweenUppercaseLetters('märkäLänttiÄäliö', 'märkä_läntti_ääliö');
163+
164+
testUnderscoreBetweenUppercaseLetters(
165+
'fooBar:spamBaz:troloLolo',
166+
'foo_bar:spam_baz:trolo_lolo'
167+
);
168+
testUnderscoreBetweenUppercaseLetters(
169+
'fooBar.spamBaz.troloLolo',
170+
'foo_bar.spam_baz.trolo_lolo'
171+
);
172+
144173
function test(camel, snake, backToCamel) {
145174
backToCamel = backToCamel || camel;
146175

@@ -162,6 +191,16 @@ describe('utils', () => {
162191
expect(camelCase(snakeCase(camel, opt), opt)).to.equal(backToCamel);
163192
});
164193
}
194+
195+
function testUnderscoreBetweenUppercaseLetters(camel, snake, backToCamel) {
196+
backToCamel = backToCamel || camel;
197+
const opt = { underscoreBetweenUppercaseLetters: true };
198+
199+
it(`${camel} --> ${snake} --> ${backToCamel}`, () => {
200+
expect(snakeCase(camel, opt)).to.equal(snake);
201+
expect(camelCase(snakeCase(camel, opt), opt)).to.equal(backToCamel);
202+
});
203+
}
165204
});
166205
});
167206

typings/objection/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,7 @@ declare namespace Objection {
12851285
export interface SnakeCaseMappersOptions {
12861286
upperCase?: boolean;
12871287
underscoreBeforeDigits?: boolean;
1288+
underscoreBetweenUppercaseLetters?: boolean;
12881289
}
12891290

12901291
export interface ColumnNameMappers {

0 commit comments

Comments
 (0)