Skip to content

Commit e5d4b68

Browse files
committed
l10n error handling and unit tests & addressing review comments
1 parent a933b37 commit e5d4b68

File tree

4 files changed

+76
-84
lines changed

4 files changed

+76
-84
lines changed

vscode/src/localiser.ts

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,68 +22,62 @@ import { extConstants } from './constants';
2222
import { FileUtils } from './utils';
2323
import { LOGGER } from './logger';
2424

25-
const DEFAULT_LANGAUGE = "en";
26-
const DEFAULT_BUNDLE_FILE = `l10n/bundle.l10n.${DEFAULT_LANGAUGE}.json`;
25+
const DEFAULT_LANGUAGE = "en";
26+
const DEFAULT_BUNDLE_FILE = `l10n/bundle.l10n.${DEFAULT_LANGUAGE}.json`;
2727
const _format2Regexp = /{([^}]+)}/g;
2828

2929
export interface l10n {
3030
value(key: string, placeholderMap?: Record<string, any>): string
31-
nbLocaleCode():string
31+
nbLocaleCode(): string
3232
}
3333

3434

3535
class l10Wrapper implements l10n {
36-
private defaultl10nMap:any;
37-
constructor(extensionId: string, defaultBundlePath: string) {
38-
let extnPath = vscode.extensions.getExtension(extensionId)?.extensionPath;
39-
let defaultBundleAbsoluteFsPath = FileUtils.toUri(`${extnPath}/${defaultBundlePath}`).fsPath;
40-
let logAndThrowError = (message:string,err:unknown) => {
41-
let errMsg = "";
42-
if(err instanceof Error){
43-
errMsg = err?.message
44-
}
45-
LOGGER.error(message+errMsg);
46-
47-
throw err;
48-
}
49-
let fileContent:string = "";
50-
try {
51-
fileContent = fs.readFileSync(defaultBundleAbsoluteFsPath,'utf-8');
52-
} catch (err) {
53-
logAndThrowError("error occured while reading bundle file : ",err);
36+
private defaultl10nMap: any;
37+
constructor(extensionId: string, defaultBundlePath: string) {
38+
let extnPath = vscode.extensions.getExtension(extensionId)?.extensionPath;
39+
let defaultBundleAbsoluteFsPath = FileUtils.toUri(`${extnPath}/${defaultBundlePath}`).fsPath;
40+
let logAndThrowError = (message: string, err: unknown) => {
41+
let errMsg = "";
42+
if (err instanceof Error) {
43+
errMsg = err?.message
5444
}
55-
try {
56-
this.defaultl10nMap = JSON.parse(fileContent);
57-
}catch (err) {
58-
let msg = "";
59-
if(err instanceof Error){
60-
msg = err?.message
61-
}
62-
logAndThrowError("error occured while parsing bundle file : ",err);
63-
throw err;
64-
}
65-
45+
LOGGER.error(message + errMsg);
46+
throw err;
6647
}
67-
68-
value(key: string, placeholderMap: Record<string, any>): string {
69-
const valueFromBundle:string = vscode.l10n.bundle ? vscode.l10n.t(key, placeholderMap) : key;
70-
const isPresentInBundle = valueFromBundle !== key;
71-
return isPresentInBundle ? valueFromBundle : this.defaultTranslation(key, placeholderMap);
48+
let fileContent: string = "";
49+
try {
50+
fileContent = fs.readFileSync(defaultBundleAbsoluteFsPath, 'utf-8');
51+
} catch (err) {
52+
logAndThrowError("error occured while reading bundle file : ", err);
7253
}
73-
defaultTranslation(key: string, placeholderMap:Record<string, any>):string{
74-
let value = this.defaultl10nMap[key];
75-
return value?this.format(value,placeholderMap):key;
54+
try {
55+
this.defaultl10nMap = JSON.parse(fileContent);
56+
} catch (err) {
57+
logAndThrowError("error occured while parsing bundle file : ", err);
7658
}
77-
nbLocaleCode(){
78-
const vscodeLanguage = vscode.env.language;
79-
if (!vscodeLanguage) return DEFAULT_LANGAUGE;
80-
const localeParts = vscodeLanguage.split(/[-_]/g);
81-
if (localeParts.length > 1) {
82-
localeParts[1] = localeParts[1].toUpperCase();
83-
}
84-
var nbFormatLocale = localeParts.join(":");
85-
return nbFormatLocale;
59+
60+
}
61+
62+
value(key: string, placeholderMap: Record<string, any>): string {
63+
const valueFromBundle: string = vscode.l10n.bundle ? vscode.l10n.t(key, placeholderMap) : key;
64+
const isPresentInBundle = valueFromBundle !== key;
65+
return isPresentInBundle ? valueFromBundle : this.defaultTranslation(key, placeholderMap);
66+
}
67+
defaultTranslation(key: string, placeholderMap: Record<string, any>): string {
68+
let value = this.defaultl10nMap[key];
69+
return value ? this.format(value, placeholderMap) : key;
70+
}
71+
nbLocaleCode() {
72+
const vscodeLanguage = vscode.env.language;
73+
if (!vscodeLanguage) return DEFAULT_LANGUAGE;
74+
const localeParts = vscodeLanguage.split(/[-_]/g);
75+
if (localeParts.length > 1) {
76+
localeParts[1] = localeParts[1].toUpperCase();
8677
}
78+
var nbFormatLocale = localeParts.join(":");
79+
return nbFormatLocale;
80+
}
8781

8882

8983
//copied from:
@@ -116,7 +110,7 @@ class l10Wrapper implements l10n {
116110
*/
117111
format(template: string, values: Record<string, unknown>): string {
118112
if (!values || Object.keys(values).length === 0) {
119-
return template;
113+
return template;
120114
}
121115
return template.replace(_format2Regexp, (match, group) => (values[group] ?? match) as string);
122116
}

vscode/src/test/unit/general/localetest.unit.test.ts

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,33 @@
1414
limitations under the License.
1515
*/
1616
import { expect } from 'chai';
17-
import { describe, it, beforeEach, afterEach } from "mocha";
17+
import { describe, it, beforeEach, before, after} from "mocha";
1818
import * as sinon from 'sinon';
1919
import * as vscode from 'vscode';
20-
import {Extension} from 'vscode';
20+
import { Extension } from 'vscode';
2121
import { LOGGER } from '../../../logger';
22-
import { mock,instance, when, reset } from "ts-mockito";
23-
var l10n:any = null;
22+
import { mock, instance, when, reset } from "ts-mockito";
23+
var l10n: any = null;
2424
import * as path from 'path';
2525
import assert = require('assert');
2626

2727
describe('localiser tests', () => {
2828
let loggerLogStub: sinon.SinonStub;
29-
let mockedExtns : typeof vscode.extensions;
30-
let extMock : Extension<any>;
31-
let mockedEnv : typeof vscode.env;
32-
let mockedL10n : typeof vscode.l10n;
33-
let currentDir = __dirname;
34-
29+
let mockedExtns: typeof vscode.extensions;
30+
let extMock: Extension<any>;
31+
let mockedEnv: typeof vscode.env;
32+
let mockedL10n: typeof vscode.l10n;
33+
let currentDir = __dirname.replace("/out/","/src/");
34+
3535
before(() => {
36-
let vscodeObj = (vscode as typeof vscode & { mockedExtns: typeof vscode.extensions ,mockedEnv: typeof vscode.env,mockedL10n: typeof vscode.l10n });
36+
let vscodeObj = (vscode as typeof vscode & { mockedExtns: typeof vscode.extensions, mockedEnv: typeof vscode.env, mockedL10n: typeof vscode.l10n });
3737
mockedExtns = vscodeObj.mockedExtns;
3838
mockedEnv = vscodeObj.mockedEnv;
3939
mockedL10n = vscodeObj.mockedL10n;
4040
extMock = mock<Extension<any>>();
41-
loggerLogStub = sinon.stub(LOGGER,"error");
42-
43-
41+
loggerLogStub = sinon.stub(LOGGER, "error");
4442
});
45-
beforeEach(()=>{
43+
beforeEach(() => {
4644
sinon.reset();
4745
reset(mockedExtns);
4846
reset(extMock);
@@ -61,32 +59,32 @@ describe('localiser tests', () => {
6159
describe('l10n tests', () => {
6260
describe('issue while reading bundle', () => {
6361
it('file not found error', () => {
64-
let msg:string|null =null;
62+
let msg: string | null = null;
6563
when(extMock?.extensionPath).thenReturn(path.join(currentDir, 'doesnt-exist'));
6664
var mkInst = instance(extMock);
6765
when(mockedExtns.getExtension("oracle.oracle-java")).thenReturn(mkInst);
68-
try{
66+
try {
6967
l10n = require('../../../localiser');
70-
}catch(e){
71-
msg = (e as any & {message:string}).message
68+
} catch (e) {
69+
msg = (e as any & { message: string }).message
7270
}
73-
assert.strictEqual(msg!!.includes("no such file or directory"),true);
71+
assert.strictEqual(msg!!.includes("no such file or directory"), true);
7472
expect(loggerLogStub.called).to.be.true;
7573
});
7674
it('file parsing error', () => {
77-
let msg:string|null =null;
78-
when(extMock?.extensionPath).thenReturn(path.join(currentDir, 'resources','corrupt'));
75+
let msg: string | null = null;
76+
when(extMock?.extensionPath).thenReturn(path.join(currentDir, 'resources', 'corrupt'));
7977
var mkInst = instance(extMock);
8078
when(mockedExtns.getExtension("oracle.oracle-java")).thenReturn(mkInst);
81-
try{
79+
try {
8280
l10n = require('../../../localiser');
83-
}catch(e){
84-
msg = (e as any & {message:string}).message
81+
} catch (e) {
82+
msg = (e as any & { message: string }).message
8583
}
86-
assert.strictEqual(msg!!.includes("Bad control character in string literal in JSON"),true);
84+
assert.strictEqual(msg!!.includes("Bad control character in string literal in JSON"), true);
8785
expect(loggerLogStub.called).to.be.true;
8886
});
89-
87+
9088
});
9189
describe('l10n initialisation tests', () => {
9290
it('l10n initialized', () => {
@@ -103,10 +101,10 @@ describe('localiser tests', () => {
103101
when(mockedExtns.getExtension("oracle.oracle-java")).thenReturn(mkExtInst);
104102
when(mockedL10n.bundle).thenReturn(undefined);
105103
let l10n = require('../../../localiser');
106-
let l10nObj = l10n.l10n as { nbLocaleCode(): string , value(key: string, placeholderMap?: Record<string, any>): string};
107-
assert.strictEqual(l10nObj.nbLocaleCode(),"en");
108-
assert.strictEqual(l10nObj.value("label1"),"label1 description");
109-
assert.strictEqual(l10nObj.value("label2",{"placeholder1":"sample data"}),"lable2 sample data description");
104+
let l10nObj = l10n.l10n as { nbLocaleCode(): string, value(key: string, placeholderMap?: Record<string, any>): string };
105+
assert.strictEqual(l10nObj.nbLocaleCode(), "en");
106+
assert.strictEqual(l10nObj.value("label1"), "label1 description");
107+
assert.strictEqual(l10nObj.value("label2", { "placeholder1": "sample data" }), "lable2 sample data description");
110108
expect(loggerLogStub.called).to.be.false;
111109
});
112110
});

vscode/src/test/unit/mocks/init.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ export const initMocks = () => {
3535

3636
const replaceImportsWithMocks = (mocks: any) => {
3737
Module._load = function (request: any, _parent: any) {
38+
3839
if (request === 'vscode') {
3940
return mocks.vscode;
40-
} else if (request.includes('localiser') && !_parent?.filename?.includes("localetest.unit.test.ts") ) {
41+
} else if (request.includes('localiser') && !(_parent?.filename?.includes("localetest.unit.test.ts") || _parent?.filename?.includes("localetest.unit.test.js")) ) {
4142
return mocks.localiser;
4243
}
4344

vscode/src/test/unit/mocks/vscode/mockVscode.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ const mockNamespaces = () => {
4141

4242
export const initMockedVSCode = () => {
4343
mockedVscodeClassesAndTypes();
44-
mockNamespaces();
45-
44+
mockNamespaces();
4645
return mockedVSCode;
4746
}
4847

0 commit comments

Comments
 (0)