@@ -717,6 +717,228 @@ describe("functionRegex", () => {
717717 } ) ;
718718} ) ;
719719
720+ describe ( "callbackCallRegex" , ( ) => {
721+ const { callbackCallRegex } = helper ;
722+ const baseOptions = {
723+ target : "result" ,
724+ source : "numbers" ,
725+ method : "reduce" ,
726+ params : [ "acc" , "el" ] ,
727+ } ;
728+
729+ it ( "returns a RegExp" , ( ) => {
730+ expect ( callbackCallRegex ( baseOptions ) ) . toBeInstanceOf ( RegExp ) ;
731+ } ) ;
732+
733+ it ( "matches arrow expression callback" , ( ) => {
734+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
735+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
736+ true ,
737+ ) ;
738+ } ) ;
739+
740+ it ( "matches arrow block callback" , ( ) => {
741+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
742+ expect (
743+ regex . test ( "result = numbers.reduce((acc, el) => { return acc + el; })" ) ,
744+ ) . toBe ( true ) ;
745+ } ) ;
746+
747+ it ( "matches function callback" , ( ) => {
748+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
749+ expect (
750+ regex . test (
751+ "result = numbers.reduce(function (acc, el) { return acc + el; })" ,
752+ ) ,
753+ ) . toBe ( true ) ;
754+ } ) ;
755+
756+ it ( "fails when target is different" , ( ) => {
757+ const regex = callbackCallRegex ( baseOptions ) ;
758+ expect ( regex . test ( "other = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
759+ false ,
760+ ) ;
761+ } ) ;
762+
763+ it ( "fails when target is only a suffix of another identifier" , ( ) => {
764+ const regex = callbackCallRegex ( baseOptions ) ;
765+ expect ( regex . test ( "myresult = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
766+ false ,
767+ ) ;
768+ } ) ;
769+
770+ it ( "fails when source is different" , ( ) => {
771+ const regex = callbackCallRegex ( baseOptions ) ;
772+ expect ( regex . test ( "result = other.reduce((acc, el) => acc + el)" ) ) . toBe (
773+ false ,
774+ ) ;
775+ } ) ;
776+
777+ it ( "fails when method is different" , ( ) => {
778+ const regex = callbackCallRegex ( baseOptions ) ;
779+ expect ( regex . test ( "result = numbers.map((acc, el) => acc + el)" ) ) . toBe (
780+ false ,
781+ ) ;
782+ } ) ;
783+
784+ it ( "fails when callback params are different" , ( ) => {
785+ const regex = callbackCallRegex ( baseOptions ) ;
786+ expect ( regex . test ( "result = numbers.reduce((x, y) => x + y)" ) ) . toBe ( false ) ;
787+ } ) ;
788+
789+ it ( "fails when callback param order is different" , ( ) => {
790+ const regex = callbackCallRegex ( baseOptions ) ;
791+ expect ( regex . test ( "result = numbers.reduce((el, acc) => el + acc)" ) ) . toBe (
792+ false ,
793+ ) ;
794+ } ) ;
795+
796+ it ( "fails when return expression does not match returns" , ( ) => {
797+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
798+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc - el)" ) ) . toBe (
799+ false ,
800+ ) ;
801+ } ) ;
802+
803+ it ( "accepts a RegExp for returns" , ( ) => {
804+ const regex = callbackCallRegex ( {
805+ ...baseOptions ,
806+ returns : / a c c \s * \+ \s * e l / ,
807+ } ) ;
808+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
809+ true ,
810+ ) ;
811+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
812+ true ,
813+ ) ;
814+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc - el)" ) ) . toBe (
815+ false ,
816+ ) ;
817+ } ) ;
818+
819+ it ( "scopes alternation in returns to the callback return expression" , ( ) => {
820+ const regex = callbackCallRegex ( {
821+ ...baseOptions ,
822+ returns : / a c c \+ e l | s o m e t h i n g E l s e / ,
823+ } ) ;
824+
825+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
826+ true ,
827+ ) ;
828+ expect ( regex . test ( "somethingElse" ) ) . toBe ( false ) ;
829+ expect (
830+ regex . test (
831+ "result = numbers.reduce((acc, el) => acc - el); somethingElse" ,
832+ ) ,
833+ ) . toBe ( false ) ;
834+ } ) ;
835+
836+ it ( "preserves non-stateful returns flags" , ( ) => {
837+ expect ( ( ) =>
838+ callbackCallRegex ( {
839+ ...baseOptions ,
840+ returns : / \p{ L} + / u,
841+ } ) ,
842+ ) . not . toThrow ( ) ;
843+
844+ const regex = callbackCallRegex ( {
845+ ...baseOptions ,
846+ returns : / \p{ L} + / u,
847+ } ) ;
848+
849+ expect ( regex . flags ) . toContain ( "u" ) ;
850+ expect ( regex . test ( "result = numbers.reduce((acc, el) => café)" ) ) . toBe ( true ) ;
851+ } ) ;
852+
853+ it ( "matches a function callback with returns" , ( ) => {
854+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
855+ expect (
856+ regex . test (
857+ "result = numbers.reduce(function (acc, el) { return acc + el; })" ,
858+ ) ,
859+ ) . toBe ( true ) ;
860+ expect (
861+ regex . test (
862+ "result = numbers.reduce(function (acc, el) { return acc - el; })" ,
863+ ) ,
864+ ) . toBe ( false ) ;
865+ } ) ;
866+
867+ it ( "matches a complex return expression using a RegExp" , ( ) => {
868+ const regex = callbackCallRegex ( {
869+ ...baseOptions ,
870+ returns : / a c c \+ e l \* \* 2 / ,
871+ } ) ;
872+ expect (
873+ regex . test ( "result = numbers.reduce((acc, el) => acc + el ** 2)" ) ,
874+ ) . toBe ( true ) ;
875+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
876+ false ,
877+ ) ;
878+ } ) ;
879+
880+ it ( "matches with let and var declarations" , ( ) => {
881+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
882+ expect (
883+ regex . test ( "let result = numbers.reduce((acc, el) => acc + el)" ) ,
884+ ) . toBe ( true ) ;
885+ expect (
886+ regex . test ( "var result = numbers.reduce((acc, el) => acc + el)" ) ,
887+ ) . toBe ( true ) ;
888+ } ) ;
889+
890+ it ( "works with extra whitespace in the callback signature" , ( ) => {
891+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
892+ expect (
893+ regex . test ( "result = numbers.reduce( ( acc , el ) => acc + el )" ) ,
894+ ) . toBe ( true ) ;
895+ } ) ;
896+
897+ it ( "works with multiline/whitespace-heavy code" , ( ) => {
898+ const regex = callbackCallRegex ( { ...baseOptions , returns : / a c c \+ e l / } ) ;
899+ const code = `const result = numbers.reduce(
900+ (acc, el) => {
901+ return acc + el;
902+ },
903+ 0
904+ )` ;
905+ expect ( regex . test ( code ) ) . toBe ( true ) ;
906+ } ) ;
907+
908+ it ( "when returns is omitted, only call shape and callback signature is required" , ( ) => {
909+ const regex = callbackCallRegex ( baseOptions ) ;
910+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc + el)" ) ) . toBe (
911+ true ,
912+ ) ;
913+ expect ( regex . test ( "result = numbers.reduce((acc, el) => acc - el)" ) ) . toBe (
914+ true ,
915+ ) ;
916+ expect (
917+ regex . test (
918+ "result = numbers.reduce(function (acc, el) { return anything; })" ,
919+ ) ,
920+ ) . toBe ( true ) ;
921+ } ) ;
922+
923+ it ( "matches an empty callback when params is []" , ( ) => {
924+ const regex = callbackCallRegex ( {
925+ target : "result" ,
926+ source : "numbers" ,
927+ method : "forEach" ,
928+ params : [ ] ,
929+ } ) ;
930+ expect ( regex . test ( "result = numbers.forEach(() => doSomething())" ) ) . toBe (
931+ true ,
932+ ) ;
933+ expect (
934+ regex . test ( "result = numbers.forEach(function () { doSomething(); })" ) ,
935+ ) . toBe ( true ) ;
936+ expect (
937+ regex . test ( "result = numbers.forEach((el) => doSomething(el))" ) ,
938+ ) . toBe ( false ) ;
939+ } ) ;
940+ } ) ;
941+
720942describe ( "prepTestComponent" , ( ) => {
721943 let MyComponent ;
722944 beforeEach ( ( ) => {
0 commit comments