From 2599be383b0425718cd176e9c751ea91e55893ff Mon Sep 17 00:00:00 2001 From: Jason Dent Date: Fri, 13 Aug 2021 17:57:53 +0200 Subject: [PATCH] fix: error output when configstore dir not accessible. fix: #1510 --- packages/cspell-lib/package-lock.json | 60 +++++++++++++++++++ packages/cspell-lib/package.json | 4 +- .../src/Settings/GlobalSettings.test.ts | 34 +++++++++-- .../cspell-lib/src/Settings/GlobalSettings.ts | 6 +- packages/cspell-lib/src/types.d.ts | 5 ++ 5 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 packages/cspell-lib/src/types.d.ts diff --git a/packages/cspell-lib/package-lock.json b/packages/cspell-lib/package-lock.json index 20bc5806e87..54474a575dd 100644 --- a/packages/cspell-lib/package-lock.json +++ b/packages/cspell-lib/package-lock.json @@ -1238,6 +1238,16 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "27.0.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.1.tgz", + "integrity": "sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==", + "dev": true, + "requires": { + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, "@types/node": { "version": "16.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.0.tgz", @@ -1539,6 +1549,15 @@ "node-releases": "^1.1.73" } }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, "bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -3811,6 +3830,12 @@ "semver": "^6.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "makeerror": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", @@ -3871,6 +3896,12 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4457,6 +4488,35 @@ "punycode": "^2.1.1" } }, + "ts-jest": { + "version": "27.0.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.4.tgz", + "integrity": "sha512-c4E1ECy9Xz2WGfTMyHbSaArlIva7Wi2p43QOMmCqjSSjHP06KXv+aT+eSY+yZMuqsMi3k7pyGsGj2q5oSl5WfQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", diff --git a/packages/cspell-lib/package.json b/packages/cspell-lib/package.json index 8d9d052aaf3..9361b8a1339 100644 --- a/packages/cspell-lib/package.json +++ b/packages/cspell-lib/package.json @@ -77,10 +77,12 @@ "@cspell/dict-python": "^1.0.37", "@types/configstore": "^5.0.1", "@types/fs-extra": "^9.0.12", + "@types/jest": "^27.0.1", "@types/node": "^16.6.0", "cspell-dict-nl-nl": "^1.1.2", "jest": "^27.0.6", "lorem-ipsum": "^2.0.3", - "rimraf": "^3.0.2" + "rimraf": "^3.0.2", + "ts-jest": "^27.0.4" } } diff --git a/packages/cspell-lib/src/Settings/GlobalSettings.test.ts b/packages/cspell-lib/src/Settings/GlobalSettings.test.ts index 09bc715878e..a1437bcaba1 100644 --- a/packages/cspell-lib/src/Settings/GlobalSettings.test.ts +++ b/packages/cspell-lib/src/Settings/GlobalSettings.test.ts @@ -1,5 +1,5 @@ -import { getGlobalConfigPath, getRawGlobalSettings, writeRawGlobalSettings } from './GlobalSettings'; import Configstore from 'configstore'; +import { mocked } from 'ts-jest/utils'; // eslint-disable-next-line jest/no-mocks-import import { clearData as clearConfigstore, @@ -8,17 +8,18 @@ import { mockAll, mockSetData, } from '../__mocks__/configstore'; +import { getGlobalConfigPath, getRawGlobalSettings, writeRawGlobalSettings } from './GlobalSettings'; -const mockLog = jest.fn(); -console.log = mockLog; -jest.mock('configstore'); - -const mockConfigstore = Configstore as jest.Mock; +const mockLog = jest.spyOn(console, 'log').mockImplementation(); +const mockError = jest.spyOn(console, 'error').mockImplementation(); +const mockConfigstore = mocked(Configstore, true); describe('Validate GlobalSettings', () => { beforeEach(() => { mockConfigstore.mockClear(); mockLog.mockClear(); + mockError.mockClear(); + mockAll.mockClear(); clearMocks(); clearConfigstore(); }); @@ -84,4 +85,25 @@ describe('Validate GlobalSettings', () => { const error2 = writeRawGlobalSettings(updated); expect(error2).toBeInstanceOf(Error); }); + + test('No Access to global settings files', () => { + mockAll.mockImplementation(() => { + throw new SystemLikeError('permission denied', 'EACCES'); + }); + const s = getRawGlobalSettings(); + expect(mockError).toHaveBeenCalledTimes(0); + expect(mockLog).toHaveBeenCalledTimes(0); + expect(s).toEqual({ + source: { + name: 'CSpell Configstore', + filename: undefined, + }, + }); + }); }); + +class SystemLikeError extends Error { + constructor(msg: string, readonly code: string) { + super(msg); + } +} diff --git a/packages/cspell-lib/src/Settings/GlobalSettings.ts b/packages/cspell-lib/src/Settings/GlobalSettings.ts index b89bcdf1618..62c564ea010 100644 --- a/packages/cspell-lib/src/Settings/GlobalSettings.ts +++ b/packages/cspell-lib/src/Settings/GlobalSettings.ts @@ -1,6 +1,6 @@ import { CSpellSettings, CSpellSettingsWithSourceTrace } from '@cspell/cspell-types'; -import { logError } from '../util/logger'; import ConfigStore from 'configstore'; +import { logError } from '../util/logger'; const packageName = 'cspell'; @@ -34,7 +34,9 @@ export function getRawGlobalSettings(): GlobalSettingsWithSource { }; } } catch (error) { - logError(error); + if (!['ENOENT', 'EACCES', 'ENOTDIR', 'EISDIR'].includes(error.code)) { + logError(error); + } } return globalConf; diff --git a/packages/cspell-lib/src/types.d.ts b/packages/cspell-lib/src/types.d.ts new file mode 100644 index 00000000000..526ee5f40fc --- /dev/null +++ b/packages/cspell-lib/src/types.d.ts @@ -0,0 +1,5 @@ +// https://github.com/facebook/jest/issues/11640 +declare namespace NodeJS { + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface Global {} +}