fileoverview author Yann Braga
  import { CategoryId } from '../utils/constants' ; import { isExpressionStatement , isCallExpression , isMemberExpression , isIdentifier , isBlockStatement , } from '../utils/ast' ; import { createStorybookRule } from '../utils/create-storybook-rule' ; export = createStorybookRule ( { name : 'use-storybook-expect' , defaultOptions : [ ] , meta : { type : 'suggestion' , fixable : 'code' , hasSuggestions : true , schema : [ ] , docs : { description : 'Use expect from `@storybook/jest`' , categories : [ CategoryId . ADDON_INTERACTIONS , CategoryId . RECOMMENDED ] , recommended : 'error' , } , messages : { updateImports : 'Update imports' , useExpectFromStorybook : 'Do not use expect from jest directly in the story. You should use from `@storybook/jest` instead.' , } , } , create ( context ) { const getExpressionStatements = ( body = [ ] ) => { return body . filter ( ( b ) => isExpressionStatement ( b ) ) ; } ; const isExpect = ( expression ) => { return ( isCallExpression ( expression ) && isMemberExpression ( expression . callee ) && isCallExpression ( expression . callee . object ) && isIdentifier ( expression . callee . object . callee ) && expression . callee . object . callee . name === 'expect' ) ; } ; const isExpectFromStorybookImported = ( node ) => { return ( node . source . value === '@storybook/jest' && node . specifiers . find ( ( spec ) => spec . imported . name === 'expect' ) ) ; } ; const checkExpectInvocations = ( blockStatement ) => { if ( ! isBlockStatement ( blockStatement ) ) { return ; } const expressionBody = blockStatement . body || [ ] ; const expressionStatements = getExpressionStatements ( expressionBody ) ; expressionStatements . forEach ( ( { expression } ) => { if ( isExpect ( expression ) ) { expectInvocations . push ( expression ) ; } } ) ; } ; let isImportingFromStorybookExpect = false ; let expectInvocations = [ ] ; return { ImportDeclaration ( node ) { if ( isExpectFromStorybookImported ( node ) ) { isImportingFromStorybookExpect = true ; } } , CallExpression ( node ) { if ( ! isIdentifier ( node . callee ) ) { return null ; } if ( node . callee . name === 'expect' ) { expectInvocations . push ( node . callee ) ; } } , 'Program:exit' : function ( ) { if ( ! isImportingFromStorybookExpect && expectInvocations . length ) { expectInvocations . forEach ( ( node ) => { context . report ( { node , messageId : 'useExpectFromStorybook' , fix : function ( fixer ) { return fixer . insertTextAfterRange ( [ 0 , 0 ] , "import { expect } from '@storybook/jest';\n" ) ; } , suggest : [ { messageId : 'updateImports' , fix : function ( fixer ) { return fixer . insertTextAfterRange ( [ 0 , 0 ] , "import { expect } from '@storybook/jest';\n" ) ; } , } , ] , } ) ; } ) ; } } , } ; } , } ) ;