Skip to content

Commit

Permalink
[New] add no-namespace rule
Browse files Browse the repository at this point in the history
Co-authored-by: Yacine Hmito <yacine.hmito@gmail.com>
Co-authored-by: Jordan Harband <ljharb@gmail.com>
  • Loading branch information
yacinehmito and ljharb committed May 9, 2020
1 parent f25a8ec commit 53a0d84
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel

## Unreleased

### Added
* add [`no-namespace`] rule ([#2640] @yacinehmito @ljharb)

[#2640]: https://github.com/yannickcr/eslint-plugin-react/pull/2640

## [7.25.3] - 2021.09.19

### Fixed
Expand Down Expand Up @@ -3437,6 +3442,7 @@ If you're still not using React 15 you can keep the old behavior by setting the
[`no-find-dom-node`]: docs/rules/no-find-dom-node.md
[`no-is-mounted`]: docs/rules/no-is-mounted.md
[`no-multi-comp`]: docs/rules/no-multi-comp.md
[`no-namespace`]: docs/rules/no-namespace.md
[`no-redundant-should-component-update`]: docs/rules/no-redundant-should-component-update.md
[`no-render-return-value`]: docs/rules/no-render-return-value.md
[`no-set-state`]: docs/rules/no-set-state.md
Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -145,6 +145,7 @@ Enable the rules that you would like to use.
|| | [react/no-find-dom-node](docs/rules/no-find-dom-node.md) | Prevent usage of findDOMNode |
|| | [react/no-is-mounted](docs/rules/no-is-mounted.md) | Prevent usage of isMounted |
| | | [react/no-multi-comp](docs/rules/no-multi-comp.md) | Prevent multiple component definition per file |
| | | [react/no-namespace](docs/rules/no-namespace.md) | Enforce that namespaces are not used in React elements |
| | | [react/no-redundant-should-component-update](docs/rules/no-redundant-should-component-update.md) | Flag shouldComponentUpdate when extending PureComponent |
|| | [react/no-render-return-value](docs/rules/no-render-return-value.md) | Prevent usage of the return value of React.render |
| | | [react/no-set-state](docs/rules/no-set-state.md) | Prevent usage of setState |
Expand Down
29 changes: 29 additions & 0 deletions docs/rules/no-namespace.md
@@ -0,0 +1,29 @@
# Enforce that namespaces are not used in React elements (react/no-namespace)

Enforces the absence of a namespace in React elements, such as with `svg:circle`, as they are not supported in React.

## Rule Details

The following patterns are considered warnings:

```jsx
<ns:TestComponent />
```

```jsx
<Ns:TestComponent />
```

The following patterns are **not** considered warnings:

```jsx
<TestComponent />
```

```jsx
<testComponent />
```

## When not to use

If you are not using React.
1 change: 1 addition & 0 deletions index.js
Expand Up @@ -67,6 +67,7 @@ const allRules = {
'no-find-dom-node': require('./lib/rules/no-find-dom-node'),
'no-is-mounted': require('./lib/rules/no-is-mounted'),
'no-multi-comp': require('./lib/rules/no-multi-comp'),
'no-namespace': require('./lib/rules/no-namespace'),
'no-set-state': require('./lib/rules/no-set-state'),
'no-string-refs': require('./lib/rules/no-string-refs'),
'no-redundant-should-component-update': require('./lib/rules/no-redundant-should-component-update'),
Expand Down
49 changes: 49 additions & 0 deletions lib/rules/no-namespace.js
@@ -0,0 +1,49 @@
/**
* @fileoverview Enforce that namespaces are not used in React elements
* @author Yacine Hmito
*/

'use strict';

const elementType = require('jsx-ast-utils/elementType');
const docsUrl = require('../util/docsUrl');
const isCreateElement = require('../util/isCreateElement');

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
meta: {
docs: {
description: 'Enforce that namespaces are not used in React elements',
category: 'Possible Errors',
recommended: false,
url: docsUrl('no-namespace')
},

schema: [{
type: 'object',
additionalProperties: false
}]
},

create(context) {
return {
CallExpression(node) {
if (isCreateElement(node, context) && node.arguments.length > 0 && node.arguments[0].type === 'Literal') {
const name = node.arguments[0].value;
if (name.indexOf(':') === -1) return undefined;
const message = `React component ${name} must not be in a namespace as React does not support them`;
context.report({node, message});
}
},
JSXOpeningElement(node) {
const name = elementType(node);
if (name.indexOf(':') === -1) return undefined;
const message = `React component ${name} must not be in a namespace as React does not support them`;
context.report({node, message});
}
};
}
};
128 changes: 128 additions & 0 deletions tests/lib/rules/no-namespace.js
@@ -0,0 +1,128 @@
/**
* @fileoverview Tests for jsx-no-namespace
* @author Yacine Hmito
*/

'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const RuleTester = require('eslint').RuleTester;
const rule = require('../../../lib/rules/no-namespace');

const parserOptions = {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
};

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-no-namespace', rule, {
valid: [{
code: '<testcomponent />'
}, {
code: 'React.createElement("testcomponent")'
}, {
code: '<testComponent />'
}, {
code: 'React.createElement("testComponent")'
}, {
code: '<test_component />'
}, {
code: 'React.createElement("test_component")'
}, {
code: '<TestComponent />'
}, {
code: 'React.createElement("TestComponent")'
}, {
code: '<object.testcomponent />'
}, {
code: 'React.createElement("object.testcomponent")'
}, {
code: '<object.testComponent />'
}, {
code: 'React.createElement("object.testComponent")'
}, {
code: '<object.test_component />'
}, {
code: 'React.createElement("object.test_component")'
}, {
code: '<object.TestComponent />'
}, {
code: 'React.createElement("object.TestComponent")'
}, {
code: '<Object.testcomponent />'
}, {
code: 'React.createElement("Object.testcomponent")'
}, {
code: '<Object.testComponent />'
}, {
code: 'React.createElement("Object.testComponent")'
}, {
code: '<Object.test_component />'
}, {
code: 'React.createElement("Object.test_component")'
}, {
code: '<Object.TestComponent />'
}, {
code: 'React.createElement("Object.TestComponent")'
}],

invalid: [{
code: '<ns:testcomponent />',
errors: [{message: 'React component ns:testcomponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("ns:testcomponent")',
errors: [{message: 'React component ns:testcomponent must not be in a namespace as React does not support them'}]
}, {
code: '<ns:testComponent />',
errors: [{message: 'React component ns:testComponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("ns:testComponent")',
errors: [{message: 'React component ns:testComponent must not be in a namespace as React does not support them'}]
}, {
code: '<ns:test_component />',
errors: [{message: 'React component ns:test_component must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("ns:test_component")',
errors: [{message: 'React component ns:test_component must not be in a namespace as React does not support them'}]
}, {
code: '<ns:TestComponent />',
errors: [{message: 'React component ns:TestComponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("ns:TestComponent")',
errors: [{message: 'React component ns:TestComponent must not be in a namespace as React does not support them'}]
}, {
code: '<Ns:testcomponent />',
errors: [{message: 'React component Ns:testcomponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("Ns:testcomponent")',
errors: [{message: 'React component Ns:testcomponent must not be in a namespace as React does not support them'}]
}, {
code: '<Ns:testComponent />',
errors: [{message: 'React component Ns:testComponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("Ns:testComponent")',
errors: [{message: 'React component Ns:testComponent must not be in a namespace as React does not support them'}]
}, {
code: '<Ns:test_component />',
errors: [{message: 'React component Ns:test_component must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("Ns:test_component")',
errors: [{message: 'React component Ns:test_component must not be in a namespace as React does not support them'}]
}, {
code: '<Ns:TestComponent />',
errors: [{message: 'React component Ns:TestComponent must not be in a namespace as React does not support them'}]
}, {
code: 'React.createElement("Ns:TestComponent")',
errors: [{message: 'React component Ns:TestComponent must not be in a namespace as React does not support them'}]
}]
});

0 comments on commit 53a0d84

Please sign in to comment.