Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for optional chaining and null coalescing #7952

Merged
merged 2 commits into from Nov 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 43 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,46 @@
## 3.3.0 (2019-xx-xx)

DRAFT

### Custom Templates

DRAFT

### Optional Chaining and Nullish Coalescing Operators

We now support the [optional chaining](https://github.com/TC39/proposal-optional-chaining) and [nullish coalescing](https://github.com/tc39/proposal-nullish-coalescing) operators!

```js
// Optional chaining
a?.(); // undefined if `a` is null/undefined
b?.c; // undefined if `b` is null/undefined

// Nullish coalescing
undefined ?? 'some other default'; // result: 'some other default'
null ?? 'some other default'; // result: 'some other default'
'' ?? 'some other default'; // result: ''
0 ?? 300; // result: 0
false ?? true; // result: false
```

**If your're using TypeScript, you will need to upgrade your `typescript` dependency to `3.7.0` or later if you wish to use the new operators.**

**If you're using Visual Studio Code 1.40 (the latest as of this release) or earlier, you will need to configure your editor if you want it to understand the new operators.**

If you're using TypeScript in your project and have already upgrade its version as described above, then you can [configure VS Code to `Use Workspace Version` of TypeScript](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions). If your project isn't using TypeScript, you can use the [JavaScript and TypeScript Nightly extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next) until VS Code releases a newer version including TypeScript `3.7.0` or newer.

### Numeric Separators

We've added support for [numeric separators](https://github.com/tc39/proposal-numeric-separator) to improve readability of numeric literals.

```js
1000000000; // Is this a billion? a hundred millions? Ten millions?
101475938.38; // what scale is this? what power of 10?

1_000_000_000; // Ah, so a billion
101_475_938.38; // And this is hundreds of millions
```

## 3.2.0 (2019-10-03)

v3.2.0 is a minor release that adds support for production profiling and ignoring TypeScript type errors to make migrating JavaScript projects to TypeScript easier. It also includes other minor bug fixes and documentation updates.
Expand Down
10 changes: 10 additions & 0 deletions packages/react-scripts/fixtures/kitchensink/template/src/App.js
Expand Up @@ -171,6 +171,11 @@ class App extends Component {
this.setFeature(f.default)
);
break;
case 'nullish-coalescing':
import('./features/syntax/NullishCoalescing').then(f =>
this.setFeature(f.default)
);
break;
case 'object-destructuring':
import('./features/syntax/ObjectDestructuring').then(f =>
this.setFeature(f.default)
Expand All @@ -181,6 +186,11 @@ class App extends Component {
this.setFeature(f.default)
);
break;
case 'optional-chaining':
import('./features/syntax/OptionalChaining').then(f =>
this.setFeature(f.default)
);
break;
case 'promises':
import('./features/syntax/Promises').then(f =>
this.setFeature(f.default)
Expand Down
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';

function load() {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
{ id: 4, name: '4' },
];
}

export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired,
};

constructor(props) {
super(props);
this.state = { users: [] };
}

async componentDidMount() {
const users = load();
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
return (
<div id="feature-nullish-coalescing">
{this.state.users.map(user => (
<div key={user.id}>{user.name ?? 'John Doe'}</div>
))}
</div>
);
}
}
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import ReactDOM from 'react-dom';
import NullishCoalescing from './NullishCoalescing';

describe('nullish coalescing', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
return new Promise(resolve => {
ReactDOM.render(<NullishCoalescing onReady={resolve} />, div);
});
});
});
@@ -0,0 +1,48 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';

function load() {
return [
{ id: 1, name: '1' },
{ id: 2, name: '2' },
{ id: 3, name: '3' },
{ id: 4, name: '4' },
];
}

export default class extends Component {
static propTypes = {
onReady: PropTypes.func.isRequired,
};

constructor(props) {
super(props);
this.state = { users: [] };
}

async componentDidMount() {
const users = load?.();
this.setState({ users });
}

componentDidUpdate() {
this.props.onReady();
}

render() {
return (
<div id="feature-optional-chaining">
{this.state.users.map(user => (
<div key={user.id}>{user?.name}</div>
))}
</div>
);
}
}
@@ -0,0 +1,19 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import ReactDOM from 'react-dom';
import OptionalChaining from './OptionalChaining';

describe('optional chaining', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
return new Promise(resolve => {
ReactDOM.render(<OptionalChaining onReady={resolve} />, div);
});
});
});