diff --git a/.prettierignore b/.prettierignore index 76527ef383b..6395f7d0aab 100644 --- a/.prettierignore +++ b/.prettierignore @@ -20,6 +20,7 @@ .dependabot/ .github/ .prettierignore +.swcrc .yarnrc .vs/ AppXManifest.xml diff --git a/.swcrc b/.swcrc new file mode 100644 index 00000000000..43f754e4b10 --- /dev/null +++ b/.swcrc @@ -0,0 +1,13 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true + } + }, + "module": { + "type": "commonjs", + "noInterop": true + }, + "env": {} +} diff --git a/copyright-header.config.json b/copyright-header.config.json index a034de574fe..9ac55dae1c9 100644 --- a/copyright-header.config.json +++ b/copyright-header.config.json @@ -4,6 +4,7 @@ "./.dependabot", "./.git", "./.github", + "./.swcrc", "./.vs", "./.vscode", "./dist", diff --git a/jest.config.base.js b/jest.config.base.js index d4b499edbb6..b548aea786f 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -21,11 +21,6 @@ module.exports = { coverageDirectory: '/test-results/unit/coverage', coverageReporters: ['text', 'lcov', 'cobertura'], displayName: '', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.json', - }, - }, moduleDirectories: ['node_modules'], moduleFileExtensions: ['ts', 'js', 'json'], moduleNameMapper: { @@ -49,6 +44,6 @@ module.exports = { testMatch: ['**/*.spec.[tj]s', '**/*.test.[tj]s'], testPathIgnorePatterns: ['/dist/', '/out/'], transform: { - '^.+\\.(ts|tsx)$': 'ts-jest', + '^.+\\.(ts|tsx|js|jsx)$': [`${__dirname}/src/tests/common/swc-transformer`], }, }; diff --git a/package.json b/package.json index e22eb05f666..a13ca65ca1c 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,11 @@ "workspaces": [ "packages/*" ], + "browserslist": [ + "chrome 88", + "edge 88", + "firefox 87" + ], "scripts": { "ada-cat": "grunt ada-cat", "assessment": "npm-run-all --serial scss:clean fastpass build:all test test:e2e test:unified", @@ -83,6 +88,7 @@ "devDependencies": { "7zip-bin": "^5.1.1", "@electron/get": "^1.12.4", + "@swc/core": "^1.2.59", "@types/applicationinsights-js": "^1.0.7", "@types/chrome": "0.0.144", "@types/enzyme": "^3.10.8", @@ -155,7 +161,6 @@ "source-map-loader": "^3.0.0", "spectron": "^13.0.0", "terser-webpack-plugin": "^5.1.3", - "ts-jest": "^27.0.2", "ts-loader": "^9.2.2", "typed-scss-modules": "^4.1.1", "typemoq": "^2.1.0", diff --git a/packages/report-e2e-tests/package.json b/packages/report-e2e-tests/package.json index e1cd3f8df4c..ae64fc212a0 100644 --- a/packages/report-e2e-tests/package.json +++ b/packages/report-e2e-tests/package.json @@ -24,7 +24,6 @@ "jest-file-snapshot": "^0.5.0", "jest-junit": "^12.1.0", "prettier": "^2.3.0", - "ts-jest": "^27.0.2", "typescript": "^4.3.2" } } diff --git a/src/reports/components/report-sections/collapsible-script-provider.tsx b/src/reports/components/report-sections/collapsible-script-provider.tsx index 57ce291b33e..5a033f9606b 100644 --- a/src/reports/components/report-sections/collapsible-script-provider.tsx +++ b/src/reports/components/report-sections/collapsible-script-provider.tsx @@ -5,10 +5,13 @@ // // The use of function() {} syntax over arrow functions is important for IE compat (see #1875). // -// The "istanbul ignore next" excludes the function from code coverage to prevent code cov from -// injecting functions that interfere with eval in the unit tests. +// The "istanbul ignore file" excludes this file from code coverage, which would otherwise cause +// unit testing with --coverage=true to inject code coverage marker functions that would prevent +// tests from being able to eval() the generated code. // -/* istanbul ignore next */ +// @ts-expect-error unused const is a workaround for https://github.com/swc-project/swc/issues/1165 +/* istanbul ignore file */ const swcIssue1165Workaround = true; + export const addEventListenerForCollapsibleSection = function (doc: Document): void { const collapsibles = doc.getElementsByClassName('collapsible-container'); diff --git a/src/reports/package/reporter-factory.ts b/src/reports/package/reporter-factory.ts index fa4ff5d62c5..2a4fdb9c570 100644 --- a/src/reports/package/reporter-factory.ts +++ b/src/reports/package/reporter-factory.ts @@ -31,6 +31,7 @@ import { HelpUrlGetter } from 'scanner/help-url-getter'; import { mapAxeTagsToGuidanceLinks } from 'scanner/map-axe-tags-to-guidance-links'; import { MessageDecorator } from 'scanner/message-decorator'; import { ResultDecorator } from 'scanner/result-decorator'; +import { RuleProcessor } from 'scanner/rule-processor'; import { FixInstructionProcessor } from '../../common/components/fix-instruction-processor'; import { getPropertyConfiguration } from '../../common/configs/unified-result-property-configurations'; import { DateProvider } from '../../common/date-provider'; @@ -91,9 +92,13 @@ const axeResultsReportGenerator = (parameters: AxeReportParameters) => { } as DocumentUtils; const messageDecorator = new MessageDecorator(configuration, new CheckMessageTransformer()); const helpUrlGetter = new HelpUrlGetter(configuration, getA11yInsightsWebRuleUrl); - const resultDecorator = new ResultDecorator(titleProvider, messageDecorator, (ruleId, axeHelpUrl) => - helpUrlGetter.getHelpUrl(ruleId, axeHelpUrl), + const ruleProcessor = new RuleProcessor(); + const resultDecorator = new ResultDecorator( + titleProvider, + messageDecorator, + (ruleId, axeHelpUrl) => helpUrlGetter.getHelpUrl(ruleId, axeHelpUrl), mapAxeTagsToGuidanceLinks, + ruleProcessor, ); const getUnifiedResults = new ConvertScanResultsToUnifiedResults(generateUID, getFixResolution, getCheckResolution).automatedChecksConversion; diff --git a/src/scanner/exposed-apis.ts b/src/scanner/exposed-apis.ts index bcb0a49684c..320299574e5 100644 --- a/src/scanner/exposed-apis.ts +++ b/src/scanner/exposed-apis.ts @@ -16,6 +16,7 @@ import { Launcher } from './launcher'; import { mapAxeTagsToGuidanceLinks } from './map-axe-tags-to-guidance-links'; import { MessageDecorator } from './message-decorator'; import { ResultDecorator } from './result-decorator'; +import { RuleProcessor } from './rule-processor'; import { ScanOptions } from './scan-options'; import { ScanParameterGenerator } from './scan-parameter-generator'; import { ScannerRuleInfo } from './scanner-rule-info'; @@ -32,11 +33,13 @@ export const scan = ( const scanParameterGenerator = new ScanParameterGenerator(ruleIncludedStatus); const documentUtils: DocumentUtils = new DocumentUtils(document); const helpUrlGetter = new HelpUrlGetter(configuration, getA11yInsightsWebRuleUrl); + const ruleProcessor = new RuleProcessor(); const resultDecorator = new ResultDecorator( documentUtils, messageDecorator, (ruleId, axeHelpUrl) => helpUrlGetter.getHelpUrl(ruleId, axeHelpUrl), mapAxeTagsToGuidanceLinks, + ruleProcessor, ); const launcher = new Launcher(axe, scanParameterGenerator, document, options); const axeResponseHandler = new AxeResponseHandler( diff --git a/src/scanner/processor.ts b/src/scanner/processor.ts deleted file mode 100644 index aebd996b026..00000000000 --- a/src/scanner/processor.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. -import { AxeNodeResult, AxeRule } from './iruleresults'; - -function normalizeText(text: string): string { - return text.toLowerCase().trim(); -} - -export namespace Processor { - // eslint-disable-next-line prefer-const - export let suppressedMessages = [ - // add messages to suppress here. Remove comment when non-empty. - ].map(normalizeText); - - export function suppressChecksByMessages( - rule: AxeRule, - removeEmptyRules = true, - ): AxeRule | null { - rule.nodes = rule.nodes.filter((nodeResult: AxeNodeResult) => { - nodeResult.any = nodeResult.any.filter((check: any) => { - const checkShown = - check.message != null - ? suppressedMessages.indexOf(normalizeText(check.message)) < 0 - : true; - - return checkShown; - }); - - return ( - nodeResult.any.length > 0 || nodeResult.none.length > 0 || nodeResult.all.length > 0 - ); - }); - - if (removeEmptyRules && rule.nodes.length === 0) { - return null; - } - - return rule; - } -} diff --git a/src/scanner/result-decorator.ts b/src/scanner/result-decorator.ts index ee2032dd899..0767d7acdf4 100644 --- a/src/scanner/result-decorator.ts +++ b/src/scanner/result-decorator.ts @@ -6,7 +6,7 @@ import { HyperlinkDefinition } from 'common/types/hyperlink-definition'; import { DocumentUtils } from './document-utils'; import { AxeRule, RuleResult, ScanResults } from './iruleresults'; import { MessageDecorator } from './message-decorator'; -import { Processor } from './processor'; +import { RuleProcessor } from './rule-processor'; export class ResultDecorator { constructor( @@ -14,6 +14,7 @@ export class ResultDecorator { private readonly messageDecorator: MessageDecorator, private readonly getHelpUrl: (ruleId: string, axeHelpUrl?: string) => string | undefined, private readonly mapAxeTagsToGuidanceLinks: (axeTags?: string[]) => HyperlinkDefinition[], + private readonly ruleProcessor: RuleProcessor, ) {} public decorateResults(results: Axe.AxeResults): ScanResults { @@ -36,7 +37,10 @@ export class ResultDecorator { ): RuleResult[] { return ruleResults.reduce((filteredArray: RuleResult[], result: AxeRule) => { this.messageDecorator.decorateResultWithMessages(result); - const processedResult = Processor.suppressChecksByMessages(result, !isInapplicable); + const processedResult = this.ruleProcessor.suppressChecksByMessages( + result, + !isInapplicable, + ); if (processedResult != null) { filteredArray.push({ diff --git a/src/scanner/rule-processor.ts b/src/scanner/rule-processor.ts new file mode 100644 index 00000000000..3d1f9f8be49 --- /dev/null +++ b/src/scanner/rule-processor.ts @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import { AxeNodeResult, AxeRule } from './iruleresults'; + +export class RuleProcessor { + normalizedSuppressedMessages: string[]; + + public constructor(suppressedMessages?: string[]) { + this.normalizedSuppressedMessages = (suppressedMessages ?? []).map(this.normalizeMessage); + } + + public suppressChecksByMessages(rule: AxeRule, removeEmptyRules = true): AxeRule | null { + rule.nodes = rule.nodes.filter((nodeResult: AxeNodeResult) => { + nodeResult.any = nodeResult.any.filter( + (check: any) => !this.shouldSuppressMessage(check.message), + ); + + return ( + nodeResult.any.length > 0 || nodeResult.none.length > 0 || nodeResult.all.length > 0 + ); + }); + + if (removeEmptyRules && rule.nodes.length === 0) { + return null; + } + + return rule; + } + + private normalizeMessage(message: string): string { + return message.toLowerCase().trim(); + } + + private shouldSuppressMessage(message: string | null): boolean { + if (message == null) { + return false; + } + + const normalizedMessage = this.normalizeMessage(message); + return this.normalizedSuppressedMessages.includes(normalizedMessage); + } +} diff --git a/src/tests/common/swc-transformer.js b/src/tests/common/swc-transformer.js new file mode 100644 index 00000000000..6077f11ee2e --- /dev/null +++ b/src/tests/common/swc-transformer.js @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +const { readFileSync } = require('fs'); +const { join } = require('path'); +const { transformSync } = require('@swc/core'); +const { merge } = require('lodash'); + +// This file can be replaced by @swc/jest once https://github.com/swc-project/jest/issues/8 resolves + +const swcrcPath = join(__dirname, '..', '..', '..', '.swcrc'); +const swcrc = JSON.parse(readFileSync(swcrcPath)); + +const jestTransformOverrides = { + jsc: { + transform: { + hidden: { + jest: true, + }, + }, + }, + module: { + type: 'commonjs', + }, +}; + +const baseTransformOptions = merge({}, swcrc, jestTransformOverrides); + +module.exports = { + process: (src, path) => { + if (/\.(t|j)sx?$/.test(path)) { + const transformOptions = merge({}, baseTransformOptions, { + filename: path, + }); + return transformSync(src, transformOptions); + } + return src; + }, +}; diff --git a/src/tests/unit/common/webextension-polyfill-ts-setup.ts b/src/tests/unit/common/webextension-polyfill-ts-setup.ts new file mode 100644 index 00000000000..1bd975871b5 --- /dev/null +++ b/src/tests/unit/common/webextension-polyfill-ts-setup.ts @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// webextension-polyfill errors on import if a global "chrome" variable is not defined +const mockChromeGlobalRequired = (window as any).chrome == null; +if (mockChromeGlobalRequired) { + (window as any).chrome = { runtime: { id: 'mocked' } }; +} + +// This must be "require" and not "import" to avoid swc hoisting the statement above the window +// setup. See https://github.com/swc-project/swc/issues/1686 and +// https://github.com/microsoft/TypeScript/pull/39764 +require('webextension-polyfill-ts'); + +if (mockChromeGlobalRequired) { + delete (window as any).chrome; +} diff --git a/src/tests/unit/tests/common/browser-adapters/browser-adapter-factory.test.ts b/src/tests/unit/tests/common/browser-adapters/browser-adapter-factory.test.ts index 4f8df6d40a5..cbf66bfff7c 100644 --- a/src/tests/unit/tests/common/browser-adapters/browser-adapter-factory.test.ts +++ b/src/tests/unit/tests/common/browser-adapters/browser-adapter-factory.test.ts @@ -1,11 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// webextension-polyfill errors on import if a global "chrome" variable is not defined -expect((window as any).chrome).toBeUndefined(); -(window as any).chrome = { runtime: { id: 'mocked' } }; -import 'webextension-polyfill-ts'; -delete (window as any).chrome; +// This must be the first import, otherwise importing webextension-polyfill-ts from within +// adapter implementations will fail +import 'tests/unit/common/webextension-polyfill-ts-setup'; import { BrowserAdapterFactory } from 'common/browser-adapters/browser-adapter-factory'; import { ChromiumAdapter } from 'common/browser-adapters/chromium-adapter'; diff --git a/src/tests/unit/tests/reports/components/report-sections/__snapshots__/collapsible-script-provider.test.ts.snap b/src/tests/unit/tests/reports/components/report-sections/__snapshots__/collapsible-script-provider.test.ts.snap index 734d0ffd682..f60ce1fccd7 100644 --- a/src/tests/unit/tests/reports/components/report-sections/__snapshots__/collapsible-script-provider.test.ts.snap +++ b/src/tests/unit/tests/reports/components/report-sections/__snapshots__/collapsible-script-provider.test.ts.snap @@ -2,36 +2,37 @@ exports[`CollapsibleScriptProvider produces script source that matches snapshot 1`] = ` "(function (doc) { - const collapsibles = doc.getElementsByClassName('collapsible-container'); - + const collapsibles = doc.getElementsByClassName(\\"collapsible-container\\"); for (let index = 0; index < collapsibles.length; index++) { const container = collapsibles.item(index); - const button = container === null || container === void 0 ? void 0 : container.querySelector('.collapsible-control'); - + const button = + container === null || container === void 0 + ? void 0 + : container.querySelector(\\".collapsible-control\\"); if (button == null) { continue; } - - button.addEventListener('click', function () { - var _a; - - const content = (_a = button.parentElement) === null || _a === void 0 ? void 0 : _a.nextElementSibling; - + button.addEventListener(\\"click\\", function () { + var ref; + const content = + (ref = button.parentElement) === null || ref === void 0 + ? void 0 + : ref.nextElementSibling; if (content == null) { throw Error(\`Expected button element's parent to have a next sibling\`); } - - const wasExpandedBefore = button.getAttribute('aria-expanded') === 'false' ? false : true; + const wasExpandedBefore = + button.getAttribute(\\"aria-expanded\\") === \\"false\\" ? false : true; const isExpandedAfter = !wasExpandedBefore; - button.setAttribute('aria-expanded', isExpandedAfter + ''); - content.setAttribute('aria-hidden', !isExpandedAfter + ''); - + button.setAttribute(\\"aria-expanded\\", isExpandedAfter + \\"\\"); + content.setAttribute(\\"aria-hidden\\", !isExpandedAfter + \\"\\"); if (isExpandedAfter) { - container.classList.remove('collapsed'); + container.classList.remove(\\"collapsed\\"); } else { - container.classList.add('collapsed'); + container.classList.add(\\"collapsed\\"); } }); } -})(document)" +})(document); +" `; diff --git a/src/tests/unit/tests/reports/components/report-sections/collapsible-script-provider.test.ts b/src/tests/unit/tests/reports/components/report-sections/collapsible-script-provider.test.ts index 5f9a9646ac1..7921320c4ba 100644 --- a/src/tests/unit/tests/reports/components/report-sections/collapsible-script-provider.test.ts +++ b/src/tests/unit/tests/reports/components/report-sections/collapsible-script-provider.test.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import { isFunction } from 'lodash'; +import { format } from 'prettier'; import { addEventListenerForCollapsibleSection, getDefaultAddListenerForCollapsibleSection, @@ -9,7 +10,10 @@ import { It, Mock, MockBehavior, Times } from 'typemoq'; describe('CollapsibleScriptProvider', () => { it('produces script source that matches snapshot', () => { - expect(getDefaultAddListenerForCollapsibleSection()).toMatchSnapshot(); + const source = getDefaultAddListenerForCollapsibleSection(); + // Required to get a consistent snapshot with --coverage=false vs --coverage=true + const formattedSource = format(source, { parser: 'babel' }).replace(/\n\n/g, '\n'); + expect(formattedSource).toMatchSnapshot(); }); it('produces script source that does not use IE-incompatible arrow functions', () => { diff --git a/src/tests/unit/tests/scanner/result-decorator.test.ts b/src/tests/unit/tests/scanner/result-decorator.test.ts index aec813604b0..714272c5b0f 100644 --- a/src/tests/unit/tests/scanner/result-decorator.test.ts +++ b/src/tests/unit/tests/scanner/result-decorator.test.ts @@ -3,9 +3,9 @@ import { DocumentUtils } from 'scanner/document-utils'; import { MessageDecorator } from 'scanner/message-decorator'; -import { Processor } from 'scanner/processor'; import { ResultDecorator } from 'scanner/result-decorator'; -import { GlobalMock, GlobalScope, IMock, It, Mock, MockBehavior, Times } from 'typemoq'; +import { RuleProcessor } from 'scanner/rule-processor'; +import { IMock, It, Mock, MockBehavior, Times } from 'typemoq'; describe('ResultDecorator', () => { let instanceStub; @@ -14,6 +14,7 @@ describe('ResultDecorator', () => { let documentUtilsMock: IMock; let messageDecoratorMock: IMock; let getHelpUrlMock: IMock<(rule, axeHelpUrl) => string>; + let ruleProcessorMock: IMock; let urlStub: string; beforeEach(() => { @@ -37,6 +38,7 @@ describe('ResultDecorator', () => { messageDecoratorMock = Mock.ofType(MessageDecorator, MockBehavior.Strict); getHelpUrlMock = Mock.ofInstance(rule => null, MockBehavior.Strict); documentUtilsMock = Mock.ofType(DocumentUtils); + ruleProcessorMock = Mock.ofType(RuleProcessor, MockBehavior.Strict); documentUtilsMock .setup(dum => dum.title()) @@ -55,6 +57,7 @@ describe('ResultDecorator', () => { messageDecoratorMock.object, getHelpUrlMock.object, stubTagToLinkMapper, + ruleProcessorMock.object, ); expect(resultDecorator).not.toBeNull(); }); @@ -86,12 +89,6 @@ describe('ResultDecorator', () => { targetPageTitle: 'test title', targetPageUrl: 'https://test_url', }; - const suppressChecksByMessagesMock = GlobalMock.ofInstance( - Processor.suppressChecksByMessages, - 'suppressChecksByMessages', - Processor, - MockBehavior.Strict, - ); messageDecoratorMock .setup(mdm => mdm.decorateResultWithMessages(instanceStub)) @@ -99,8 +96,8 @@ describe('ResultDecorator', () => { getHelpUrlMock.setup(gchm => gchm(instanceStub.id, It.isAny())).returns(() => urlStub); - suppressChecksByMessagesMock - .setup(scbmm => scbmm(instanceStub, true)) + ruleProcessorMock + .setup(m => m.suppressChecksByMessages(instanceStub, true)) .returns(result => { return result; }) @@ -111,14 +108,12 @@ describe('ResultDecorator', () => { messageDecoratorMock.object, getHelpUrlMock.object, mockTagToLinkMapper.object, + ruleProcessorMock.object, ); - let decoratedResult; - GlobalScope.using(suppressChecksByMessagesMock).with(() => { - decoratedResult = testSubject.decorateResults(nonEmptyResultStub); - }); + const decoratedResult = testSubject.decorateResults(nonEmptyResultStub); expect(decoratedResult).toEqual(resultStubWithGuidanceLinks); - suppressChecksByMessagesMock.verifyAll(); + ruleProcessorMock.verifyAll(); documentUtilsMock.verifyAll(); messageDecoratorMock.verifyAll(); mockTagToLinkMapper.verifyAll(); @@ -174,12 +169,6 @@ describe('ResultDecorator', () => { targetPageTitle: 'test title', targetPageUrl: 'https://test_url', }; - const suppressChecksByMessagesMock = GlobalMock.ofInstance( - Processor.suppressChecksByMessages, - 'suppressChecksByMessages', - Processor, - MockBehavior.Strict, - ); tagToLinkMapperMock .setup(m => m(['tag1'])) @@ -206,15 +195,15 @@ describe('ResultDecorator', () => { .setup(gchm => gchm(inapplicableInstance.id, It.isAny())) .returns(() => urlStub2); - suppressChecksByMessagesMock - .setup(scbmm => scbmm(violationInstance, true)) + ruleProcessorMock + .setup(m => m.suppressChecksByMessages(violationInstance, true)) .returns(result => { return result; }) .verifiable(); - suppressChecksByMessagesMock - .setup(scbmm => scbmm(inapplicableInstance, false)) + ruleProcessorMock + .setup(m => m.suppressChecksByMessages(inapplicableInstance, false)) .returns(result => { return result; }) @@ -225,16 +214,14 @@ describe('ResultDecorator', () => { messageDecoratorMock.object, getHelpUrlMock.object, tagToLinkMapperMock.object, + ruleProcessorMock.object, + ); + const decoratedResult = testSubject.decorateResults( + nonEmptyResultWithInapplicable as any, ); - let decoratedResult; - GlobalScope.using(suppressChecksByMessagesMock).with(() => { - decoratedResult = testSubject.decorateResults( - nonEmptyResultWithInapplicable as any, - ); - }); expect(decoratedResult).toEqual(resultStubWithGuidanceLinks); - suppressChecksByMessagesMock.verifyAll(); + ruleProcessorMock.verifyAll(); documentUtilsMock.verifyAll(); messageDecoratorMock.verifyAll(); tagToLinkMapperMock.verifyAll(); @@ -254,12 +241,6 @@ describe('ResultDecorator', () => { targetPageTitle: 'test title', targetPageUrl: 'https://test_url', }; - const suppressChecksByMessagesMock = GlobalMock.ofInstance( - Processor.suppressChecksByMessages, - 'suppressChecksByMessages', - Processor, - MockBehavior.Strict, - ); instanceStub.nodes = []; @@ -267,8 +248,8 @@ describe('ResultDecorator', () => { .setup(mdm => mdm.decorateResultWithMessages(instanceStub)) .verifiable(Times.once()); - suppressChecksByMessagesMock - .setup(scbmm => scbmm(instanceStub, true)) + ruleProcessorMock + .setup(m => m.suppressChecksByMessages(instanceStub, true)) .returns(result => { return null; }) @@ -279,14 +260,13 @@ describe('ResultDecorator', () => { messageDecoratorMock.object, getHelpUrlMock.object, tagToLinkMapper, + ruleProcessorMock.object, ); - let decoratedResult; - GlobalScope.using(suppressChecksByMessagesMock).with(() => { - decoratedResult = testSubject.decorateResults(nonEmptyResultStub); - }); + + const decoratedResult = testSubject.decorateResults(nonEmptyResultStub); expect(decoratedResult).toEqual(emptyResultsStub); - suppressChecksByMessagesMock.verifyAll(); + ruleProcessorMock.verifyAll(); documentUtilsMock.verifyAll(); messageDecoratorMock.verifyAll(); }); diff --git a/src/tests/unit/tests/scanner/processor.test.ts b/src/tests/unit/tests/scanner/rule-processor.test.ts similarity index 86% rename from src/tests/unit/tests/scanner/processor.test.ts rename to src/tests/unit/tests/scanner/rule-processor.test.ts index bfff984f658..b9cb11fe393 100644 --- a/src/tests/unit/tests/scanner/processor.test.ts +++ b/src/tests/unit/tests/scanner/rule-processor.test.ts @@ -1,20 +1,19 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { AxeNodeResult, AxeRule, FormattedCheckResult } from '../../../../scanner/iruleresults'; -import { Processor } from '../../../../scanner/processor'; -import { DictionaryStringTo } from '../../../../types/common-types'; +import { AxeNodeResult, AxeRule, FormattedCheckResult } from 'scanner/iruleresults'; +import { RuleProcessor } from 'scanner/rule-processor'; +import { DictionaryStringTo } from 'types/common-types'; -describe('getDefaultAxeRules', () => { +describe('RuleProcessor', () => { let suppressedChecks: DictionaryStringTo; let nonSuppressedCheck: FormattedCheckResult; + let testSubject: RuleProcessor; beforeEach(() => { - Processor.suppressedMessages = [ + testSubject = new RuleProcessor([ 'Required ARIA child role not present: listbox', 'Required ARIA child role not present: textbox', - ].map(message => { - return message.toLowerCase().trim(); - }); + ]); suppressedChecks = { requiredChildrenListbox: { @@ -65,7 +64,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule); + const actual = testSubject.suppressChecksByMessages(initialAxeRule); expect(actual).toEqual(expectedAxeRule); }); @@ -84,7 +83,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule); + const actual = testSubject.suppressChecksByMessages(initialAxeRule); expect(actual).toEqual(initialAxeRule); }); @@ -108,7 +107,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule, false); + const actual = testSubject.suppressChecksByMessages(initialAxeRule, false); expect(actual).toEqual(expectedAxeRule); }); @@ -138,7 +137,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule); + const actual = testSubject.suppressChecksByMessages(initialAxeRule); expect(actual).toEqual(expectedAxeRule); }); @@ -170,7 +169,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule); + const actual = testSubject.suppressChecksByMessages(initialAxeRule); expect(actual).toEqual(expectedAxeRule); }); @@ -189,7 +188,7 @@ describe('getDefaultAxeRules', () => { description: 'description', }; - const actual = Processor.suppressChecksByMessages(initialAxeRule); + const actual = testSubject.suppressChecksByMessages(initialAxeRule); expect(actual).toBeNull(); }); }); diff --git a/yarn.lock b/yarn.lock index 87dadae19c9..2bc04a235d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1588,6 +1588,19 @@ resolved "https://registry.yarnpkg.com/@microsoft/load-themed-styles/-/load-themed-styles-1.10.29.tgz#2d8505a36b70a2efff9f03a842843d9d9ca31cd3" integrity sha512-gkorI+klJXCA86RcXvKkKVvQd32EMf3IXLqQV8JV7PskLAISyUVEq/pgJjdw8KLbusHdptx6IxVsG25VphKIFQ== +"@napi-rs/triples@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.2.tgz#2ce4c6a78568358772008f564ee5009093d20a19" + integrity sha512-EL3SiX43m9poFSnhDx4d4fn9SSaqyO2rHsCNhETi9bWPmjXK3uPJ0QpPFtx39FEdHcz1vJmsiW41kqc0AgvtzQ== + +"@node-rs/helper@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@node-rs/helper/-/helper-1.1.1.tgz#1cbac64cd5bcaa038d9c23bc951c75667dc981c1" + integrity sha512-HnCdrCXKOm2jdzAdIGk4fey5xn8BuCK0+CiWwc3oMIxaQG1/0v24ZlDJV5DiSQo7vYy+1wKmOVRY3ErmZZm7+A== + dependencies: + "@napi-rs/triples" "^1.0.2" + tslib "^2.2.0" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1807,6 +1820,74 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@swc/core-android-arm64@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-android-arm64/-/core-android-arm64-1.2.59.tgz#0c4fef0b5be7a9f4008bbd2c7d527da2f4717a70" + integrity sha512-shCOuQxeZH+cAkF7jZVj1eneiM01N9sNAOllRntbFCLlN0xoTV5YkNYLoYvS5D4eNxdfZ2U0rGinq558EKz2HA== + +"@swc/core-darwin-arm64@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.59.tgz#a81fddb8d824efdfa160f55bd2eb6ade2a3b444b" + integrity sha512-7r+lngfxq6jTck/QwPmSzLF4N0XgeCQewsn8d63VDrr5sKbyrAFlRa8JM517CEgPNxKsO+vjCWgoWL964mSIqA== + +"@swc/core-darwin-x64@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.2.59.tgz#bb7de9fdfe7a851a56bd5973c64152b376e05020" + integrity sha512-yOnaHaJN+nIGQ58WOKY1SHmaXTO9GT35YF0zBF+ZwpKohucLFJ2byJt7gpdbt//LZKPrIhsVhQvFRBCAdL6XGQ== + +"@swc/core-freebsd-x64@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.59.tgz#9f574809489d185e16563cff6c34ba0e12cbee57" + integrity sha512-SKZuxOj9WAkZpT3ta6hurAvr4ufUw6V+ZC5H1Spe6qqZRbX6zvu8oQXuyIpxMjw5XXd8wdlncBa0gEA1NPukqg== + +"@swc/core-linux-arm-gnueabihf@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.59.tgz#48856a81e8e92b1d98296ff0a5cba515c547c060" + integrity sha512-Xp4qSehBZUtutDkyFpfUHVV90/9MpQ7OdvgvBMQOPffO3ehZW/kLe6cs+6wp51VITL1mZBc8pwfs8/PVZ5ECKg== + +"@swc/core-linux-arm64-gnu@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.59.tgz#4c2e708cd42ece1faa57f9242a58be7ed2f1920c" + integrity sha512-AmzDrOsq1OQCFWRlmJ8+L79F44bjwP0JZtM/eURm9cHDBmo8/Q952HQTZzJjEMsqdzLIvawdGAIzCn23GeEGGA== + +"@swc/core-linux-x64-gnu@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.59.tgz#9ef668244e81455d9799783d752168ea78db6853" + integrity sha512-/xpmfzdSavJbYnVSuTVR/nkJIPiA+/V3qhRRuD/sRDcaB7tVTpIFhKbAeKxYNvFH17l2NRjwGB7/eQijq0fIsA== + +"@swc/core-linux-x64-musl@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.59.tgz#5fcad14e1731a50a807b1f7dfc4fdd99fa0baba1" + integrity sha512-vssTkwI/Z1tT99KzQsDI34ZVkI/62zJelGSOn+Nj5mnuZcMRvtlS/dnWe5yUtC5wmPdYyVQi6+b9GxiUVG9wmg== + +"@swc/core-win32-ia32-msvc@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.59.tgz#66897da0c645e651cc385e05e4dcb13c64c9bbff" + integrity sha512-um/seOHH1vxLzQ7O7wYddK0zPIz2HkWf3boL06CXZx/ZfgSI42YTYoKcK2lsnp97e6EMtJEergxHvW+0aCe1gQ== + +"@swc/core-win32-x64-msvc@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.59.tgz#64f06fd0d47c24b2c7b253f76749ea48fdf47041" + integrity sha512-8uLWzcSnIj8D1IY+Pgr0etPz1PwtcmMeWqhPJ+9hJDK3mYMOmBfOUyIJkQZguXrb1cCLUfDhztkke8uB3evlaQ== + +"@swc/core@^1.2.59": + version "1.2.59" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.2.59.tgz#3d81380c5a1bc27ebf124ad797a9bfa09c16775a" + integrity sha512-cJMdaoUQShGC3dtohgEyuBmA8iIdMhikmFlzuCmcd5kWso36/ZnKHvcB09UTf3pFw4w8y4yoWDX9nLT2nqfWyg== + dependencies: + "@node-rs/helper" "^1.0.0" + optionalDependencies: + "@swc/core-android-arm64" "^1.2.59" + "@swc/core-darwin-arm64" "^1.2.59" + "@swc/core-darwin-x64" "^1.2.59" + "@swc/core-freebsd-x64" "^1.2.59" + "@swc/core-linux-arm-gnueabihf" "^1.2.59" + "@swc/core-linux-arm64-gnu" "^1.2.59" + "@swc/core-linux-x64-gnu" "^1.2.59" + "@swc/core-linux-x64-musl" "^1.2.59" + "@swc/core-win32-ia32-msvc" "^1.2.59" + "@swc/core-win32-x64-msvc" "^1.2.59" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -3485,13 +3566,6 @@ browserslist@^4.14.5, browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.71" -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - bser@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -3532,7 +3606,7 @@ buffer-fill@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= -buffer-from@1.x, buffer-from@^1.0.0: +buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -5700,7 +5774,7 @@ fast-glob@^3.0.3, fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -7866,7 +7940,7 @@ jest-snapshot@^27.0.2: pretty-format "^27.0.2" semver "^7.3.2" -jest-util@^27.0.0, jest-util@^27.0.2: +jest-util@^27.0.2: version "27.0.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7" integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA== @@ -8062,13 +8136,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@2.x, json5@^2.1.2, json5@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" - integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== - dependencies: - minimist "^1.2.5" - json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -8076,6 +8143,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.2, json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -8477,7 +8551,7 @@ lodash.zip@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= -lodash@4.x, lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.19, lodash@~4.17.21: +lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.7.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.19, lodash@~4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8566,11 +8640,6 @@ make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-error@1.x: - version "1.3.5" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" - integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== - make-fetch-happen@^8.0.9: version "8.0.14" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" @@ -8904,11 +8973,6 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@1.x, mkdirp@^1.0.0, mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -8916,6 +8980,11 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdir dependencies: minimist "^1.2.5" +mkdirp@^1.0.0, mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -11337,18 +11406,18 @@ semver-diff@^3.1.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -12401,22 +12470,6 @@ truncate-utf8-bytes@^1.0.0: dependencies: utf8-byte-length "^1.0.1" -ts-jest@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.0.2.tgz#acc1525d5fd25c107c777c3b80a11365db579aa1" - integrity sha512-pozjHOOfm+sbv9kXCvTFVyDntWvuJztzkNFql/akD75hSMZ2jsbidVauOhBRImAopXohqcLtPK/NTTIS8Y49Ug== - dependencies: - 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" - ts-loader@^9.2.2: version "9.2.2" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.2.tgz#416333900621c82d5eb1b1f6dea4114111f096bf" @@ -12447,6 +12500,11 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +tslib@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -13398,11 +13456,6 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== -yargs-parser@20.x, yargs-parser@^20.2.3: - version "20.2.7" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" - integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== - yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -13411,6 +13464,11 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.3: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + yargs@^13.3.0, yargs@^15.0.2, yargs@^15.3.1, yargs@^16.0.3, yargs@^16.2.0: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"