Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@
"kind": "build",
"isDefault": true
}
},
{
"label": "Typescript (vr-tests) watch",
"type": "process",
"command": "node",
"args": [
"./scripts/node_modules/typescript/bin/tsc",
"-p",
"apps/vr-tests/tsconfig.json",
"-w",
"--noEmit"
],
"problemMatcher": "$tsc",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
20 changes: 10 additions & 10 deletions apps/vr-tests/src/stories/PeoplePicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 1,
imageUrl: TestImages.personaFemale,
imageInitials: 'PV',
primaryText: 'Annie Lindqvist',
text: 'Annie Lindqvist',
secondaryText: 'Designer',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -22,7 +22,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 2,
imageUrl: TestImages.personaMale,
imageInitials: 'AR',
primaryText: 'Aaron Reid',
text: 'Aaron Reid',
secondaryText: 'Designer',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -32,7 +32,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 3,
imageUrl: TestImages.personaMale,
imageInitials: 'AL',
primaryText: 'Alex Lundberg',
text: 'Alex Lundberg',
secondaryText: 'Software Developer',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -42,7 +42,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 4,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Roko Kolar',
text: 'Roko Kolar',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -52,7 +52,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 5,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Alex Lundberg1',
text: 'Alex Lundberg1',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -62,7 +62,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 6,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Alex Lundberg2',
text: 'Alex Lundberg2',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -72,7 +72,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 7,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Alex Lundberg2',
text: 'Alex Lundberg2',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -82,7 +82,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 8,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Alex Lundberg3',
text: 'Alex Lundberg3',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -92,7 +92,7 @@ const people: (IPersonaProps & { key: string | number })[] = [
key: 9,
imageUrl: TestImages.personaMale,
imageInitials: 'RK',
primaryText: 'Alex Lundberg4',
text: 'Alex Lundberg4',
secondaryText: 'Financial Analyst',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm',
Expand All @@ -110,7 +110,7 @@ const suggestionProps = {
suggestionsContainerAriaLabel: 'Suggested contacts'
};

const getTextFromItem = (persona: IPersonaProps): string => persona.primaryText as string;
const getTextFromItem = (persona: IPersonaProps): string => persona.text as string;

const getPeople = () => people;

Expand Down
20 changes: 10 additions & 10 deletions apps/vr-tests/src/stories/Persona.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import * as React from 'react';
import Screener, { Steps } from 'screener-storybook/src/screener';
import { storiesOf } from '@storybook/react';
import { FabricDecorator } from '../utilities';
import { Persona, PersonaPresence, PersonaSize } from 'office-ui-fabric-react';
import { IPersonaProps, Persona, PersonaPresence, PersonaSize } from 'office-ui-fabric-react';
import { TestImages } from '../common/TestImages';

const examplePersona = {
const examplePersona: IPersonaProps = {
imageUrl: TestImages.personaFemale,
imageInitials: 'AL',
primaryText: 'Annie Lindqvist',
text: 'Annie Lindqvist',
secondaryText: 'Software Engineer',
tertiaryText: 'In a meeting',
optionalText: 'Available at 4:00pm'
Expand Down Expand Up @@ -104,37 +104,37 @@ storiesOf('Persona', module)
<div>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.away'
text='PersonaPresence.away'
presence={ PersonaPresence.away }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.blocked'
text='PersonaPresence.blocked'
presence={ PersonaPresence.blocked }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.busy'
text='PersonaPresence.busy'
presence={ PersonaPresence.busy }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.dnd'
text='PersonaPresence.dnd'
presence={ PersonaPresence.dnd }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.none'
text='PersonaPresence.none'
presence={ PersonaPresence.none }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.offline'
text='PersonaPresence.offline'
presence={ PersonaPresence.offline }
/>
<Persona
{ ...examplePersona }
primaryText='PersonaPresence.online'
text='PersonaPresence.online'
presence={ PersonaPresence.online }
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Deprecate Persona's primaryText prop and add replacement text prop.",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "jagore@microsoft.com"
}
59 changes: 59 additions & 0 deletions ghdocs/BestPractices/Deprecation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Deprecation Guidelines

This guide outlines recommendations for deprecating API behavior, particularly related to component props.

An example PR following these steps can be found here:
**https://github.com/OfficeDev/office-ui-fabric-react/pull/4811**

## Deprecation Steps
1. Make sure snapshot tests exist covering existing props functionality as a reference check against deprecation changes.
- Make sure the prop you're changing has representation in the snapshot output. Sometimes this may require getting the component under test into a certain state.
1. Keep the tests using deprecated props named in a file with deprecated suffix, such as `Persona.test.tsx` -> `Persona.deprecated.test.tsx`.
1. Copy the test's snapshot output (or ensure it's the same if regenerated.)
1. Modify existing tests to use new prop.
- Snapshot output should be identical in most cases, particularly if props naming is the only thing changing.
1. Add new property to interface.
1. Optionally, temporarily comment out old prop to help find all uses throughout code base and change. Take care that as of writing some uses are not covered by TypeScript as part of build, such as some objects created in tests without type declaration and Screener tests in `apps/vr-tests`.
- If you use VS Code, there is a task available to help aid called `Typescript (vr-tests) watch` which you can run via `Tasks -> Run Task`. You may have to rebuild occasionally to get the types reflected across packages correctly.
1. Move deprecated prop to end of interface, update comments with deprecation description and add @deprecated.

```tsx
/**
* Primary text to display, usually the name of the person.
* @deprecated Use 'text' instead.
*/
primaryText?: string;
```

1. Update component as needed to support both deprecated and new props.
1. Make sure old and new tests pass.
1. Add call to warnDeprecations in constructor, like:

```tsx
constructor(props: IPersonaCoinProps) {
super(props);

// 'primaryText' is deprecated and 'text' should be used instead
this._warnDeprecations({ 'primaryText': 'text' });
}
```
1. warnDeprecations will most likely cause deprecated tests to fail, requiring mocking of warnDeprecations. Please make note to clear mock at end of tests as shown below.

```tsx
// Prevent warn deprecations from failing test
const Utilities = require('@uifabric/utilities/lib/warn');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be using require here. Amongst other things, Utilities will not be typed as a result.

Recommend:

import * as Utilities from '@uifabric/utilities/lib/warn';
jest.spyOn(Utilities, 'warnDeprecations').mockImplementation(() => { /** no impl **/ });

The only thing I'm a little less sure about is whether there is a need to cleanup the mock after the fact, as the mock seems localized to the tests within the file/module only.

If you do a beforeEach/afterEach reset though, you can then have asserts again warnDeprecation being triggered.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this should also be mockReset and not mockClear

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anybody know of a way to spyOn or mock exported modules from index modules like Utilities.ts? I don't like using the full path show above as most test imports are using import { setRTL } from '../../Utilities'; but I haven't found a workaround yet.


describe('MyTests', () => {
beforeAll(() => {
Utilities.warnDeprecations = jest.fn().mockImplementation(() => { /** no impl **/ });
});

afterAll(() => {
Utilities.warnDeprecations.mockClear();
});

// tests ...
});
```


Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as renderer from 'react-test-renderer';
import { ActivityItem } from './ActivityItem';
import { Icon } from '../../Icon';
import { TestImages } from '../../common/TestImages';
import { IPersonaSharedProps } from '../Persona';

const defaultProps = {
key: 1,
Expand All @@ -12,17 +13,17 @@ const defaultProps = {
timeStamp: 'timestamp text'
};

const defaultPersonaProps = [
const defaultPersonaProps: IPersonaSharedProps[] = [
{
imageInitials: 'TN',
primaryText: 'Test Name'
text: 'Test Name'
},
{
imageUrl: TestImages.personaFemale
},
{
imageInitials: 'AN',
primaryText: 'Another Name'
text: 'Another Name'
},
{
imageUrl: TestImages.personaMale
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ export class ActivityItemCompactExample extends React.Component<React.Props<Acti
activityPersonas: [
{
imageInitials: 'PT',
primaryText: 'Robert Larsson'
text: 'Robert Larsson'
},
{
imageUrl: TestImages.personaMale
},
{
imageInitials: 'EC',
primaryText: 'Eduarda Costa'
text: 'Eduarda Costa'
}
],
isCompact: true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { css, classNamesFunction } from '../../../Utilities';
import { ActivityItem } from '../ActivityItem';
import { ActivityItem, IActivityItemProps } from '..';
import {
getStyles,
IActivityItemExampleStyleProps,
Expand All @@ -15,7 +15,7 @@ export class ActivityItemPersonaExample extends React.Component<React.Props<Acti
const classNames = getClassNames(getStyles);

// tslint:disable:jsx-no-lambda
const activityItemExamples = [
const activityItemExamples: (IActivityItemProps & { key: string | number })[] = [
{
key: 1,
activityDescription: [
Expand Down Expand Up @@ -43,7 +43,7 @@ export class ActivityItemPersonaExample extends React.Component<React.Props<Acti
activityPersonas: [
{
imageInitials: 'JM',
primaryText: 'Javiera Márquez'
text: 'Javiera Márquez'
},
{
imageUrl: TestImages.personaFemale
Expand All @@ -62,7 +62,7 @@ export class ActivityItemPersonaExample extends React.Component<React.Props<Acti
activityPersonas: [
{
imageInitials: 'RL',
primaryText: 'Robert Larsson'
text: 'Robert Larsson'
},
{
imageUrl: TestImages.personaMale
Expand All @@ -84,14 +84,14 @@ export class ActivityItemPersonaExample extends React.Component<React.Props<Acti
activityPersonas: [
{
imageInitials: 'JC',
primaryText: 'Jin Cheng'
text: 'Jin Cheng'
},
{
imageUrl: TestImages.personaMale
},
{
imageInitials: 'AL',
primaryText: 'Annie Lindqvist'
text: 'Annie Lindqvist'
},
{
imageUrl: TestImages.personaFemale
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ export class CheckboxImplementationExamples extends React.Component<{}, ICheckbo

private _renderPersonaLabel(props: ICheckboxProps): JSX.Element {
const DEFAULT_IMAGE_URL = '/_layouts/15/userphoto.aspx?size=S&accountname=';
return <Persona primaryText={ props.label } imageUrl={ DEFAULT_IMAGE_URL } size={ PersonaSize.size32 } />;
return <Persona text={ props.label } imageUrl={ DEFAULT_IMAGE_URL } size={ PersonaSize.size32 } />;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class DocumentCardActivity extends BaseComponent<IDocumentCardActivityPro
<div className={ css('ms-DocumentCardActivity-avatar', styles.avatar) }>
<PersonaCoin
imageInitials={ person.initials }
primaryText={ person.name }
text={ person.name }
imageUrl={ person.profileImageSrc }
initialsColor={ person.initialsColor }
allowPhoneInitials={ person.allowPhoneInitials }
Expand Down
Loading