Skip to content

Commit

Permalink
Initial implementation of jsx-no-namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
yacinehmito committed May 9, 2020
1 parent da7a045 commit fbd325a
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -175,6 +175,7 @@ Enable the rules that you would like to use.
* [react/jsx-no-comment-textnodes](docs/rules/jsx-no-comment-textnodes.md): Comments inside children section of tag should be placed inside braces
* [react/jsx-no-duplicate-props](docs/rules/jsx-no-duplicate-props.md): Enforce no duplicate props
* [react/jsx-no-literals](docs/rules/jsx-no-literals.md): Prevent using string literals in React component definition
* [react/jsx-no-namespace](docs/rules/jsx-no-namespace.md): Enforce that namespaces are not used in JSX
* [react/jsx-no-script-url](docs/rules/jsx-no-script-url.md): Forbid `javascript:` URLs
* [react/jsx-no-target-blank](docs/rules/jsx-no-target-blank.md): Forbid `target="_blank"` attribute without `rel="noreferrer"`
* [react/jsx-no-undef](docs/rules/jsx-no-undef.md): Disallow undeclared variables in JSX
Expand Down
29 changes: 29 additions & 0 deletions docs/rules/jsx-no-namespace.md
@@ -0,0 +1,29 @@
# Enforce that namespaces are not used in JSX (react/jsx-no-namespace)

Enforces the absence of a namespace in JSX components, 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 JSX.
2 changes: 2 additions & 0 deletions index.js
Expand Up @@ -35,6 +35,7 @@ const allRules = {
'jsx-no-comment-textnodes': require('./lib/rules/jsx-no-comment-textnodes'),
'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'),
'jsx-no-literals': require('./lib/rules/jsx-no-literals'),
'jsx-no-namespace': require('./lib/rules/jsx-no-namespace'),
'jsx-no-script-url': require('./lib/rules/jsx-no-script-url'),
'jsx-no-target-blank': require('./lib/rules/jsx-no-target-blank'),
'jsx-no-useless-fragment': require('./lib/rules/jsx-no-useless-fragment'),
Expand Down Expand Up @@ -126,6 +127,7 @@ module.exports = {
'react/jsx-key': 2,
'react/jsx-no-comment-textnodes': 2,
'react/jsx-no-duplicate-props': 2,
'react/jsx-no-namespace': 2,
'react/jsx-no-target-blank': 2,
'react/jsx-no-undef': 2,
'react/jsx-uses-react': 2,
Expand Down
40 changes: 40 additions & 0 deletions lib/rules/jsx-no-namespace.js
@@ -0,0 +1,40 @@
/**
* @fileoverview Enforce that namespaces are not used in JSX
* @author Yacine Hmito
*/

'use strict';

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

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

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

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

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

'use strict';

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

const RuleTester = require('eslint').RuleTester;
const rule = require('../../../lib/rules/jsx-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: '<testComponent />'
}, {
code: '<test_component />'
}, {
code: '<TestComponent />'
}, {
code: '<object.testcomponent />'
}, {
code: '<object.testComponent />'
}, {
code: '<object.test_component />'
}, {
code: '<object.TestComponent />'
}, {
code: '<Object.testcomponent />'
}, {
code: '<Object.testComponent />'
}, {
code: '<Object.test_component />'
}, {
code: '<Object.TestComponent />'
}],

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

0 comments on commit fbd325a

Please sign in to comment.