Skip to content
Open
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
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module.exports = {
'prefer-action-list-item-onselect': require('./rules/prefer-action-list-item-onselect'),
'enforce-css-module-identifier-casing': require('./rules/enforce-css-module-identifier-casing'),
'enforce-css-module-default-import': require('./rules/enforce-css-module-default-import'),
'no-deprecated-octicon': require('./rules/no-deprecated-octicon'),
},
configs: {
recommended: require('./configs/recommended'),
Expand Down
234 changes: 234 additions & 0 deletions src/rules/__tests__/no-deprecated-octicon.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
'use strict'

const {RuleTester} = require('eslint')
const rule = require('../no-deprecated-octicon')

const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
})

ruleTester.run('no-deprecated-octicon', rule, {
valid: [
// Not an Octicon component
{
code: `import {Button} from '@primer/react'
export default function App() {
return <Button>Click me</Button>
}`,
},

// Already using direct icon import
{
code: `import {XIcon} from '@primer/octicons-react'
export default function App() {
return <XIcon />
}`,
},

// Octicon without icon prop (edge case - can't transform)
{
code: `import {Octicon} from '@primer/react/deprecated'
export default function App() {
return <Octicon />
}`,
},
],

invalid: [
// Basic case: simple Octicon with icon prop
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <Octicon icon={XIcon} />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <XIcon />
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Octicon with additional props
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <Octicon icon={XIcon} size={16} className="test" />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <XIcon size={16} className="test" />
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Octicon with spread props
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
const props = { size: 16 }
return <Octicon {...props} icon={XIcon} className="test" />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
const props = { size: 16 }
return <XIcon {...props} className="test" />
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Octicon with closing tag
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <Octicon icon={XIcon}>
<span>Content</span>
</Octicon>
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon} from '@primer/octicons-react'
export default function App() {
return <XIcon>
<span>Content</span>
</XIcon>
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Multiple Octicons
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return (
<div>
<Octicon icon={XIcon} />
<Octicon icon={CheckIcon} size={24} />
</div>
)
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return (
<div>
<XIcon />
<CheckIcon size={24} />
</div>
)
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Complex conditional case - now provides autofix
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return <Octicon icon={condition ? XIcon : CheckIcon} />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return condition ? <XIcon /> : <CheckIcon />
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Complex conditional case with props - applies props to both components
{
code: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return <Octicon icon={condition ? XIcon : CheckIcon} size={16} className="test" />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
import {XIcon, CheckIcon} from '@primer/octicons-react'
export default function App() {
return condition ? <XIcon size={16} className="test" /> : <CheckIcon size={16} className="test" />
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Dynamic icon access - now provides autofix
{
code: `import {Octicon} from '@primer/react/deprecated'
export default function App() {
const icons = { x: XIcon }
return <Octicon icon={icons.x} />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
export default function App() {
const icons = { x: XIcon }
return React.createElement(icons.x, {})
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},

// Dynamic icon access with props
{
code: `import {Octicon} from '@primer/react/deprecated'
export default function App() {
const icons = { x: XIcon }
return <Octicon icon={icons.x} size={16} className="btn-icon" />
}`,
output: `import {Octicon} from '@primer/react/deprecated'
export default function App() {
const icons = { x: XIcon }
return React.createElement(icons.x, {size: 16, className: "btn-icon"})
}`,
errors: [
{
messageId: 'replaceDeprecatedOcticon',
},
],
},
],
})
Loading
Loading