From f265899df6ee6e10ebba6656f53e6d5f87935de4 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 25 Aug 2023 12:34:00 +0200 Subject: [PATCH 01/10] disableTypeTests --- .../react-conformance/src/defaultTests.tsx | 36 +++++++------- .../react-conformance/src/isConformant.ts | 48 +++++++++++++++++-- packages/react-conformance/src/types.ts | 42 ++++++++++++++-- 3 files changed, 100 insertions(+), 26 deletions(-) diff --git a/packages/react-conformance/src/defaultTests.tsx b/packages/react-conformance/src/defaultTests.tsx index f511c42a7b57e..1eb5d36d7013f 100644 --- a/packages/react-conformance/src/defaultTests.tsx +++ b/packages/react-conformance/src/defaultTests.tsx @@ -3,7 +3,7 @@ import * as _ from 'lodash'; import * as path from 'path'; import { render } from '@testing-library/react'; -import { TestObject, IsConformantOptions } from './types'; +import { IsConformantOptions, DefaultTestObject } from './types'; import { defaultErrorMessages } from './defaultErrorMessages'; import { ComponentDoc } from 'react-docgen-typescript'; import { getPackagePath, getCallbackArguments, validateCallbackArguments } from './utils/index'; @@ -32,9 +32,9 @@ function getTargetElement( /* eslint-disable @typescript-eslint/naming-convention */ -export const defaultTests: TestObject = { +export const defaultTests: DefaultTestObject = { /** Component file exports a valid React element type */ - 'exports-component': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'exports-component': (testInfo: IsConformantOptions) => { it(`exports component from file under correct name (exports-component)`, () => { const { componentPath, Component, displayName } = testInfo; const componentFile = require(componentPath); @@ -52,7 +52,7 @@ export const defaultTests: TestObject = { }, /** Component file exports a valid React element and can render it */ - 'component-renders': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-renders': (testInfo: IsConformantOptions) => { it(`renders (component-renders)`, () => { try { const { requiredProps, Component, renderOptions } = testInfo; @@ -67,7 +67,7 @@ export const defaultTests: TestObject = { * If functional component: component has a displayName * Else: component's constructor is a named function and matches displayName */ - 'component-has-displayname': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-has-displayname': (testInfo: IsConformantOptions) => { const { Component } = testInfo; it(`has a displayName or constructor name (component-has-displayname)`, () => { @@ -86,7 +86,7 @@ export const defaultTests: TestObject = { }, /** Component handles ref */ - 'component-handles-ref': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-handles-ref': (testInfo: IsConformantOptions) => { it(`handles ref (component-handles-ref)`, () => { // This test simply verifies that the passed ref is applied to an element *anywhere* in the DOM const { Component, requiredProps, elementRefName = 'ref', renderOptions } = testInfo; @@ -108,7 +108,7 @@ export const defaultTests: TestObject = { }, /** Component has ref applied to the root component DOM node */ - 'component-has-root-ref': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-has-root-ref': (testInfo: IsConformantOptions) => { it(`applies ref to root element (component-has-root-ref)`, () => { const { renderOptions, Component, requiredProps, elementRefName = 'ref', primarySlot = 'root' } = testInfo; @@ -153,7 +153,7 @@ export const defaultTests: TestObject = { * (In the extremely unlikely event that someone has a compelling need for the native functionality * in the future, it can be added under an `htmlSize` prop.) */ - 'omits-size-prop': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'omits-size-prop': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => { const sizeType = componentInfo.props.size?.type?.name; if (!sizeType || componentInfo.props.htmlSize) { return; @@ -188,7 +188,7 @@ export const defaultTests: TestObject = { }, /** Component file handles classname prop */ - 'component-handles-classname': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-handles-classname': (testInfo: IsConformantOptions) => { const { Component, requiredProps, renderOptions } = testInfo; const testClassName = 'testComponentClassName'; let handledClassName = false; @@ -253,10 +253,10 @@ export const defaultTests: TestObject = { }, /** Component file has assigned and exported static classnames object */ - 'component-has-static-classnames-object': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'component-has-static-classnames-object': (testInfo: IsConformantOptions) => { const { componentPath, Component, testOptions = {}, requiredProps, renderOptions } = testInfo; - const componentName = componentInfo.displayName; + const componentName = testInfo.displayName; const classNamePrefix = testOptions?.['component-has-static-classname']?.prefix ?? 'fui'; const componentClassName = `${classNamePrefix}-${componentName}`; const exportName = `${componentName[0].toLowerCase()}${componentName.slice(1)}ClassNames`; @@ -353,7 +353,7 @@ export const defaultTests: TestObject = { }, /** Constructor/component name matches filename */ - 'name-matches-filename': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'name-matches-filename': (testInfo: IsConformantOptions) => { it(`Component/constructor name matches filename (name-matches-filename)`, () => { try { const { componentPath, displayName } = testInfo; @@ -367,7 +367,7 @@ export const defaultTests: TestObject = { }, /** Ensures component is exported at top level allowing `import { Component } from 'packageName'` */ - 'exported-top-level': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'exported-top-level': (testInfo: IsConformantOptions) => { if (testInfo.isInternal) { return; } @@ -385,7 +385,7 @@ export const defaultTests: TestObject = { }, /** Ensures component has top level file in package/src/componentName */ - 'has-top-level-file': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'has-top-level-file': (testInfo: IsConformantOptions) => { if (testInfo.isInternal) { return; } @@ -403,7 +403,7 @@ export const defaultTests: TestObject = { }, /** Ensures aria attributes are kebab cased */ - 'kebab-aria-attributes': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'kebab-aria-attributes': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => { it(`uses kebab-case for aria attributes (kebab-aria-attributes)`, () => { const invalidProps = Object.keys(componentInfo.props).filter( prop => prop.startsWith('aria') && !/^aria-[a-z]+$/.test(prop), @@ -418,7 +418,7 @@ export const defaultTests: TestObject = { // TODO: Test last word of callback name against list of valid verbs /** Ensures that components have consistent custom callback names i.e. on[Part][Event] */ - 'consistent-callback-names': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'consistent-callback-names': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => { it(`has consistent custom callback names (consistent-callback-names)`, () => { const { testOptions = {} } = testInfo; const propNames = Object.keys(componentInfo.props); @@ -445,7 +445,7 @@ export const defaultTests: TestObject = { }, /** Ensures that components have consistent callback arguments (ev, data) */ - 'consistent-callback-args': (componentInfo, testInfo, tsProgram) => { + 'consistent-callback-args': (testInfo, componentInfo, tsProgram) => { it('has consistent custom callback arguments (consistent-callback-args)', () => { const { testOptions = {} } = testInfo; @@ -501,7 +501,7 @@ export const defaultTests: TestObject = { }, /** If the primary slot is specified, it receives native props other than 'className' and 'style' */ - 'primary-slot-gets-native-props': (componentInfo: ComponentDoc, testInfo: IsConformantOptions) => { + 'primary-slot-gets-native-props': (testInfo: IsConformantOptions) => { it(`applies correct native props to the primary and root slots (primary-slot-gets-native-props)`, () => { try { const { Component, requiredProps, primarySlot = 'root', renderOptions } = testInfo; diff --git a/packages/react-conformance/src/isConformant.ts b/packages/react-conformance/src/isConformant.ts index 2711019ebf321..f63607b593838 100644 --- a/packages/react-conformance/src/isConformant.ts +++ b/packages/react-conformance/src/isConformant.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; -import { IsConformantOptions } from './types'; +import { ConformanceTest, DefaultTestObject, IsConformantOptions } from './types'; import { defaultTests } from './defaultTests'; import { merge } from './utils/merge'; import { createTsProgram } from './utils/createTsProgram'; @@ -17,6 +17,7 @@ export function isConformant(...testInfo: Partial(...testInfo: Partial(...testInfo: Partial(...testInfo: Partial { for (const test of Object.keys(extraTests)) { if (!disabledTests.includes(test)) { - extraTests[test](componentInfo, mergedOptions, tsProgram); + extraTests[test](mergedOptions, componentInfo, tsProgram); } } }); @@ -63,3 +69,39 @@ export function isConformant(...testInfo: Partial { + for (const test of Object.keys(extraTests)) { + if (!disabledTests.includes(test)) { + const func = extraTests[test]; + if (isNonTypeTest(func)) { + func(mergedOptions); + } + } + } + }); + } +} + +function isNonTypeTest( + func: ConformanceTest, +): func is (testInfo: IsConformantOptions) => void { + return func.length === 1; +} diff --git a/packages/react-conformance/src/types.ts b/packages/react-conformance/src/types.ts index 5e950e4e3af70..4fdc202760f40 100644 --- a/packages/react-conformance/src/types.ts +++ b/packages/react-conformance/src/types.ts @@ -50,6 +50,14 @@ export interface IsConformantOptions { * If there are tests that aren't supposed to run on a component, this allows to opt out of any test. */ disabledTests?: string[]; + + /** + * Disable tests that verify the component's prop types. + * These tests require TypeScript information. + * It is recommended to keep these tests enabled, but they can be disabled in a large repo to improve test performance and memory consumption. + */ + disableTypeTests?: boolean; + /** * Optional flag that means the component is not exported at top level. * @defaultvalue false @@ -104,12 +112,36 @@ export interface IsConformantOptions { tsConfig?: Partial<{ configName: string; configDir: string }>; } -export type ConformanceTest = ( - componentInfo: ComponentDoc, - testInfo: IsConformantOptions, - tsProgram: ts.Program, -) => void; +export type ConformanceTest = + | ((testInfo: IsConformantOptions) => void) + | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void) + | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void); export interface TestObject { [key: string]: ConformanceTest; } + +export interface DefaultTestObject { + 'exports-component': (testInfo: IsConformantOptions) => void; + 'component-renders': (testInfo: IsConformantOptions) => void; + 'component-has-displayname': (testInfo: IsConformantOptions) => void; + 'component-handles-ref': (testInfo: IsConformantOptions) => void; + 'component-has-root-ref': (testInfo: IsConformantOptions) => void; + 'omits-size-prop': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; + 'component-handles-classname': (testInfo: IsConformantOptions) => void; + 'component-has-static-classnames-object': ( + testInfo: IsConformantOptions, + componentInfo: ComponentDoc, + ) => void; + 'name-matches-filename': (testInfo: IsConformantOptions) => void; + 'exported-top-level': (testInfo: IsConformantOptions) => void; + 'has-top-level-file': (testInfo: IsConformantOptions) => void; + 'kebab-aria-attributes': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; + 'consistent-callback-names': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; + 'consistent-callback-args': ( + testInfo: IsConformantOptions, + componentInfo: ComponentDoc, + tsProgram: ts.Program, + ) => void; + 'primary-slot-gets-native-props': (testInfo: IsConformantOptions) => void; +} From 5c27cf7740524e73b00f46f16172eb23185f432e Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 25 Aug 2023 12:37:10 +0200 Subject: [PATCH 02/10] chglog --- ...t-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json diff --git a/change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json b/change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json new file mode 100644 index 0000000000000..300706b40e331 --- /dev/null +++ b/change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: add option `disableTypeTests` to disable tests that require TypeScript information", + "packageName": "@fluentui/react-conformance", + "email": "yuanboxue@microsoft.com", + "dependentChangeType": "patch" +} From 0406e18ee7babeaddd53f6c55a91bb021c953832 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Fri, 25 Aug 2023 13:32:25 +0200 Subject: [PATCH 03/10] api --- packages/react-conformance/etc/react-conformance.api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-conformance/etc/react-conformance.api.md b/packages/react-conformance/etc/react-conformance.api.md index 7f841f59461b7..1298ba4c42f26 100644 --- a/packages/react-conformance/etc/react-conformance.api.md +++ b/packages/react-conformance/etc/react-conformance.api.md @@ -10,7 +10,7 @@ import { render } from '@testing-library/react'; import * as ts from 'typescript'; // @public (undocumented) -export type ConformanceTest = (componentInfo: ComponentDoc, testInfo: IsConformantOptions, tsProgram: ts.Program) => void; +export type ConformanceTest = ((testInfo: IsConformantOptions) => void) | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void) | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void); // @public (undocumented) export function isConformant(...testInfo: Partial>[]): void; @@ -20,6 +20,7 @@ export interface IsConformantOptions { Component: React_2.ComponentType; componentPath: string; disabledTests?: string[]; + disableTypeTests?: boolean; displayName: string; elementRefName?: string; extraTests?: TestObject; From 7bb77d9adec087257a2563d2216812a14c204003 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 10:48:04 +0200 Subject: [PATCH 04/10] fix other test --- .../react-conformance-griffel/src/overridesWin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-components/react-conformance-griffel/src/overridesWin.ts b/packages/react-components/react-conformance-griffel/src/overridesWin.ts index 39507d334c715..7b60cae6b8c88 100644 --- a/packages/react-components/react-conformance-griffel/src/overridesWin.ts +++ b/packages/react-components/react-conformance-griffel/src/overridesWin.ts @@ -28,7 +28,7 @@ async function getReactComponent( * A conformance test for mergeClasses() that ensures that a classname from props is passed as a last param, * i.e. ensures that user's overrides have higher priority. */ -export const overridesWin: ConformanceTest = (componentInfo, testInfo) => { +export const overridesWin: ConformanceTest = (testInfo: IsConformantOptions) => { const testOptions = testInfo.testOptions as | (TestOptions & { [OVERRIDES_WIN_TEST_NAME]?: OverridesWinTestOptions }) | undefined; From 7b1efcd1939d1d875d488dad95a87b7ccf069ab3 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 10:55:06 +0200 Subject: [PATCH 05/10] changelog --- ...-conformance-aaea8ec6-7ee2-46d1-a0fb-931f2254779d.json} | 0 ...mance-griffel-ef67da63-fb0a-472f-a11d-c8bc0419c3a3.json | 7 +++++++ 2 files changed, 7 insertions(+) rename change/{@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json => @fluentui-react-conformance-aaea8ec6-7ee2-46d1-a0fb-931f2254779d.json} (100%) create mode 100644 change/@fluentui-react-conformance-griffel-ef67da63-fb0a-472f-a11d-c8bc0419c3a3.json diff --git a/change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json b/change/@fluentui-react-conformance-aaea8ec6-7ee2-46d1-a0fb-931f2254779d.json similarity index 100% rename from change/@fluentui-react-conformance-d44653b1-0e34-46bf-8b91-4d74a8e507c4.json rename to change/@fluentui-react-conformance-aaea8ec6-7ee2-46d1-a0fb-931f2254779d.json diff --git a/change/@fluentui-react-conformance-griffel-ef67da63-fb0a-472f-a11d-c8bc0419c3a3.json b/change/@fluentui-react-conformance-griffel-ef67da63-fb0a-472f-a11d-c8bc0419c3a3.json new file mode 100644 index 0000000000000..f322e69de85e1 --- /dev/null +++ b/change/@fluentui-react-conformance-griffel-ef67da63-fb0a-472f-a11d-c8bc0419c3a3.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: internal type update with @fluentui/react-conformance version bump", + "packageName": "@fluentui/react-conformance-griffel", + "email": "yuanboxue@microsoft.com", + "dependentChangeType": "none" +} From b6aa69b2a6fba4197f2be6c91620d111a45a8076 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 11:19:48 +0200 Subject: [PATCH 06/10] type polish --- .../src/overridesWin.ts | 4 +- .../etc/react-conformance.api.md | 7 ++- packages/react-conformance/src/index.ts | 2 +- packages/react-conformance/src/types.ts | 49 +++++++++---------- 4 files changed, 30 insertions(+), 32 deletions(-) diff --git a/packages/react-components/react-conformance-griffel/src/overridesWin.ts b/packages/react-components/react-conformance-griffel/src/overridesWin.ts index 7b60cae6b8c88..4f54f63ec779b 100644 --- a/packages/react-components/react-conformance-griffel/src/overridesWin.ts +++ b/packages/react-components/react-conformance-griffel/src/overridesWin.ts @@ -1,4 +1,4 @@ -import type { IsConformantOptions, ConformanceTest, TestOptions } from '@fluentui/react-conformance'; +import type { IsConformantOptions, BaseConformanceTest, TestOptions } from '@fluentui/react-conformance'; import './matchers/index'; export const OVERRIDES_WIN_TEST_NAME = 'make-styles-overrides-win'; @@ -28,7 +28,7 @@ async function getReactComponent( * A conformance test for mergeClasses() that ensures that a classname from props is passed as a last param, * i.e. ensures that user's overrides have higher priority. */ -export const overridesWin: ConformanceTest = (testInfo: IsConformantOptions) => { +export const overridesWin: BaseConformanceTest = testInfo => { const testOptions = testInfo.testOptions as | (TestOptions & { [OVERRIDES_WIN_TEST_NAME]?: OverridesWinTestOptions }) | undefined; diff --git a/packages/react-conformance/etc/react-conformance.api.md b/packages/react-conformance/etc/react-conformance.api.md index 1298ba4c42f26..c79d1cd9026e8 100644 --- a/packages/react-conformance/etc/react-conformance.api.md +++ b/packages/react-conformance/etc/react-conformance.api.md @@ -10,7 +10,10 @@ import { render } from '@testing-library/react'; import * as ts from 'typescript'; // @public (undocumented) -export type ConformanceTest = ((testInfo: IsConformantOptions) => void) | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void) | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void); +export type BaseConformanceTest = ConformanceTest; + +// @public (undocumented) +export type ConformanceTest = (testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void; // @public (undocumented) export function isConformant(...testInfo: Partial>[]): void; @@ -42,7 +45,7 @@ export interface IsConformantOptions { // @public (undocumented) export interface TestObject { // (undocumented) - [key: string]: ConformanceTest; + [key: string]: BaseConformanceTest | ConformanceTest; } // @public diff --git a/packages/react-conformance/src/index.ts b/packages/react-conformance/src/index.ts index a901708e93cc3..068b19bf5deed 100644 --- a/packages/react-conformance/src/index.ts +++ b/packages/react-conformance/src/index.ts @@ -1,2 +1,2 @@ export { isConformant } from './isConformant'; -export type { ConformanceTest, IsConformantOptions, TestObject, TestOptions } from './types'; +export type { BaseConformanceTest, ConformanceTest, IsConformantOptions, TestObject, TestOptions } from './types'; diff --git a/packages/react-conformance/src/types.ts b/packages/react-conformance/src/types.ts index 4fdc202760f40..487687f65ffd0 100644 --- a/packages/react-conformance/src/types.ts +++ b/packages/react-conformance/src/types.ts @@ -112,36 +112,31 @@ export interface IsConformantOptions { tsConfig?: Partial<{ configName: string; configDir: string }>; } -export type ConformanceTest = - | ((testInfo: IsConformantOptions) => void) - | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void) - | ((testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void); +export type BaseConformanceTest = ConformanceTest; +export type ConformanceTest = ( + testInfo: IsConformantOptions, + componentInfo: ComponentDoc, + tsProgram: ts.Program, +) => void; export interface TestObject { - [key: string]: ConformanceTest; + [key: string]: BaseConformanceTest | ConformanceTest; } export interface DefaultTestObject { - 'exports-component': (testInfo: IsConformantOptions) => void; - 'component-renders': (testInfo: IsConformantOptions) => void; - 'component-has-displayname': (testInfo: IsConformantOptions) => void; - 'component-handles-ref': (testInfo: IsConformantOptions) => void; - 'component-has-root-ref': (testInfo: IsConformantOptions) => void; - 'omits-size-prop': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; - 'component-handles-classname': (testInfo: IsConformantOptions) => void; - 'component-has-static-classnames-object': ( - testInfo: IsConformantOptions, - componentInfo: ComponentDoc, - ) => void; - 'name-matches-filename': (testInfo: IsConformantOptions) => void; - 'exported-top-level': (testInfo: IsConformantOptions) => void; - 'has-top-level-file': (testInfo: IsConformantOptions) => void; - 'kebab-aria-attributes': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; - 'consistent-callback-names': (testInfo: IsConformantOptions, componentInfo: ComponentDoc) => void; - 'consistent-callback-args': ( - testInfo: IsConformantOptions, - componentInfo: ComponentDoc, - tsProgram: ts.Program, - ) => void; - 'primary-slot-gets-native-props': (testInfo: IsConformantOptions) => void; + 'exports-component': BaseConformanceTest; + 'component-renders': BaseConformanceTest; + 'component-has-displayname': BaseConformanceTest; + 'component-handles-ref': BaseConformanceTest; + 'component-has-root-ref': BaseConformanceTest; + 'omits-size-prop': ConformanceTest; + 'component-handles-classname': BaseConformanceTest; + 'component-has-static-classnames-object': ConformanceTest; + 'name-matches-filename': BaseConformanceTest; + 'exported-top-level': BaseConformanceTest; + 'has-top-level-file': BaseConformanceTest; + 'kebab-aria-attributes': ConformanceTest; + 'consistent-callback-names': ConformanceTest; + 'consistent-callback-args': ConformanceTest; + 'primary-slot-gets-native-props': BaseConformanceTest; } From f3b979bf9176114868e962f330f20866a3fd4d2d Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 11:51:41 +0200 Subject: [PATCH 07/10] fix n* --- .../test/specs/commonTests/extraConformanceTests.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/fluentui/react-northstar/test/specs/commonTests/extraConformanceTests.tsx b/packages/fluentui/react-northstar/test/specs/commonTests/extraConformanceTests.tsx index d8ce93d18f195..8a204a596cf41 100644 --- a/packages/fluentui/react-northstar/test/specs/commonTests/extraConformanceTests.tsx +++ b/packages/fluentui/react-northstar/test/specs/commonTests/extraConformanceTests.tsx @@ -22,7 +22,7 @@ const parseDocblock = (docblock: string) => { */ export const extraConformanceTests: TestObject = { /** Component has a docblock with 5 to 25 words */ - 'has-docblock': (componentInfo, testInfo) => { + 'has-docblock': (_testInfo, componentInfo) => { const maxWords = 25; const minWords = 5; @@ -37,7 +37,7 @@ export const extraConformanceTests: TestObject = { }, /** If the component is a subcomponent, ensure its parent has the subcomponent as static property */ - 'is-static-property-of-parent': (componentInfo, testInfo) => { + 'is-static-property-of-parent': testInfo => { const { componentPath, displayName, Component } = testInfo; const componentFolder = componentPath.replace(path.basename(componentPath) + path.extname(componentPath), ''); const dirName = path.basename(componentFolder).replace(path.extname(componentFolder), ''); From cb359c1e095ac0fe41ca215a0215055ad7e37098 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 11:57:42 +0200 Subject: [PATCH 08/10] type update --- packages/react-conformance/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-conformance/src/types.ts b/packages/react-conformance/src/types.ts index 487687f65ffd0..95ab76f99cd23 100644 --- a/packages/react-conformance/src/types.ts +++ b/packages/react-conformance/src/types.ts @@ -112,7 +112,7 @@ export interface IsConformantOptions { tsConfig?: Partial<{ configName: string; configDir: string }>; } -export type BaseConformanceTest = ConformanceTest; +export type BaseConformanceTest = (testInfo: IsConformantOptions) => void; export type ConformanceTest = ( testInfo: IsConformantOptions, componentInfo: ComponentDoc, From 783467dfcf6f02dcd092f0f898d19bf2d89d3ab0 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 12:08:42 +0200 Subject: [PATCH 09/10] api --- packages/react-conformance/etc/react-conformance.api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-conformance/etc/react-conformance.api.md b/packages/react-conformance/etc/react-conformance.api.md index c79d1cd9026e8..d4d2f8e30a391 100644 --- a/packages/react-conformance/etc/react-conformance.api.md +++ b/packages/react-conformance/etc/react-conformance.api.md @@ -10,7 +10,7 @@ import { render } from '@testing-library/react'; import * as ts from 'typescript'; // @public (undocumented) -export type BaseConformanceTest = ConformanceTest; +export type BaseConformanceTest = (testInfo: IsConformantOptions) => void; // @public (undocumented) export type ConformanceTest = (testInfo: IsConformantOptions, componentInfo: ComponentDoc, tsProgram: ts.Program) => void; From 76632b49c8c7c4914b9756e6a54f14db0fef47d7 Mon Sep 17 00:00:00 2001 From: YuanboXue-Amber Date: Mon, 28 Aug 2023 12:17:54 +0200 Subject: [PATCH 10/10] type+comment --- packages/react-conformance/src/isConformant.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/react-conformance/src/isConformant.ts b/packages/react-conformance/src/isConformant.ts index f63607b593838..ae8754414c143 100644 --- a/packages/react-conformance/src/isConformant.ts +++ b/packages/react-conformance/src/isConformant.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; -import { ConformanceTest, DefaultTestObject, IsConformantOptions } from './types'; +import { BaseConformanceTest, ConformanceTest, DefaultTestObject, IsConformantOptions } from './types'; import { defaultTests } from './defaultTests'; import { merge } from './utils/merge'; import { createTsProgram } from './utils/createTsProgram'; @@ -100,8 +100,9 @@ function runNonTypeTests(mergedOptions: IsConformantOptions) { } } -function isNonTypeTest( - func: ConformanceTest, -): func is (testInfo: IsConformantOptions) => void { +/** + * Verifies that a test function has only one parameter. If so, this test does not require TS info. + */ +function isNonTypeTest(func: ConformanceTest): func is BaseConformanceTest { return func.length === 1; }