React Native 测试组件与 Moti 和 Jest 错误:SyntaxError: Unexpected token 'export'

发布于 01-13 15:06 字数 6136 浏览 7 评论 0原文

我正在尝试测试使用 moti 库创建的组件,但是当我运行测试时显示错误。 Moti 文档没有显示任何有关如何正确模拟组件的内容。

({"Object.":function(module,exports,require,__dirname,__filename,jest){export * from '@motify/core'; ^^^^^^

SyntaxError: Unexpected token 'export'

      1 | import {View, TouchableOpacity, Text, FlatList, Pressable} from 'react-native';
    > 2 | import {AnimatePresence, MotiView} from "moti";
        | ^
      3 | import React from "react";
      4 | import {WLText} from "##ui/components/elements/wl-text";
      5 | import {styles} from './wl-autocomplete-suggestion.style';

我的组件

   import {View, TouchableOpacity, Text, FlatList, Pressable} from 'react-native';
import {AnimatePresence, MotiView} from "moti";
import React from "react";
import {WLText} from "##ui/components/elements/wl-text";
import {styles} from './wl-autocomplete-suggestion.style';
import PropTypes from "prop-types";
import _ from 'lodash';


export const WlAutocompleteSuggestionsComponent = (props) => {

  const {showSugestions, data, onPress, onPressItem, searchText, categories} = props
  const {suggestions, brands,} = data || []


  const highLightWord = (word, highlight) => {
    const match = _.words(word?.toLowerCase(), RegExp(highlight?.toLowerCase()));
    const notMatch = _.replace(word.toLowerCase(), match, "");
    return (
      <View style={{flexDirection: "row"}}>
        <WLText style={{fontWeight: 'bold'}} text={match}/>
        <WLText text={notMatch}/>
      </View>
    );
  };

  return (
    <AnimatePresence>
      {showSugestions && suggestions.length > 0 &&
          <MotiView
              from={{
                opacity: 0.5,
              }}
              animate={{
                opacity: 1
              }}

              transition={{
                type:"timing",
                duration: 300,
              }}
              exit={{
                opacity: 0.5,
              }}

              style={styles.container}>
              <Pressable
                  onPress={onPress}
                  style={styles.backgroundSylte}/>
              <View
                  style={styles.contentWrapper}>
                  <TouchableOpacity onPress={() => onPressItem(suggestions[0])}>
                    {highLightWord(suggestions[0], searchText)}
                  </TouchableOpacity>
                  <View style={styles.brandsContainer}>
                      <View style={styles.brandsWrapper}>
                          <View
                              style={styles.brandsTagsWrapper}>
                            {categories?.map((item) => <View
                              key={item.name}
                              onTouchEnd={(e) => {
                                e.stopPropagation()
                              }}>
                              <TouchableOpacity
                                onPress={() => {
                                  onPressItem(item.name)
                                }}
                                style={styles.tagContainer}>
                                <WLText style={{fontStyle: 'oblique'}} text={'In '}/>
                                <WLText text={`${item.name}`}
                                        styleName={'NORMAL_MULTILINE'} ellipsizeAtLine={2} testID={`_TITLE`}/>
                              </TouchableOpacity>
                            </View>)}

                            {brands.map((item) => <View
                              key={item}
                              onTouchEnd={(e) => {
                                e.stopPropagation()
                              }}>
                              <TouchableOpacity
                                onPress={() => {
                                  onPressItem(item)
                                }}
                                style={styles.tagContainer}>
                                <WLText text={item}
                                        styleName={'NORMAL_MULTILINE'} ellipsizeAtLine={2} testID={`_TITLE`}/>
                              </TouchableOpacity>
                            </View>)}
                          </View>
                      </View>
                  </View>
                  <View>
                    {suggestions.length > 0 &&
                        <View style={{justifyContent: 'center',}}>
                          {suggestions.slice(1).map((item) => <View
                            key={item}
                            onTouchEnd={(e) => {
                              e.stopPropagation()
                            }}>
                            <TouchableOpacity
                              onPress={() => {
                                onPressItem(item)
                              }}
                              style={styles.itemStyle}>
                              {highLightWord(item, searchText)}
                            </TouchableOpacity>
                          </View>)}
                        </View>
                    }
                  </View>
              </View>
          </MotiView>
      }
    </AnimatePresence>
  )
}

WlAutocompleteSuggestionsComponent.propTypes = {
  showSugestions: PropTypes.bool,
  searchText: PropTypes.string,
  data: PropTypes.object,
  onPressItem: PropTypes.func,
  onPress: PropTypes.func,
  categories: PropTypes.array
};

测试代码

import {render} from "@testing-library/react-native";
import React from "react";
import {
  WlAutocompleteSuggestionsComponent
} from "../wl-autocomplete-suggestions-component";

describe('WLAutocompleteSuggestions', ()=>{
  it('Renders Properly', ()=>{
    const {  getByTestId } = render(<WlAutocompleteSuggestionsComponent />);
    const titleText = getByTestId('_TITLE');
    expect(titleText).toBeTruthy()

  })
})

i am trying to test a component that was created with the moti library but when i run the test show me the error. The Moti documentation doesnt show anything about how to mock the component properly.

({"Object.":function(module,exports,require,__dirname,__filename,jest){export * from '@motify/core';
^^^^^^

SyntaxError: Unexpected token 'export'

      1 | import {View, TouchableOpacity, Text, FlatList, Pressable} from 'react-native';
    > 2 | import {AnimatePresence, MotiView} from "moti";
        | ^
      3 | import React from "react";
      4 | import {WLText} from "##ui/components/elements/wl-text";
      5 | import {styles} from './wl-autocomplete-suggestion.style';

my component

   import {View, TouchableOpacity, Text, FlatList, Pressable} from 'react-native';
import {AnimatePresence, MotiView} from "moti";
import React from "react";
import {WLText} from "##ui/components/elements/wl-text";
import {styles} from './wl-autocomplete-suggestion.style';
import PropTypes from "prop-types";
import _ from 'lodash';


export const WlAutocompleteSuggestionsComponent = (props) => {

  const {showSugestions, data, onPress, onPressItem, searchText, categories} = props
  const {suggestions, brands,} = data || []


  const highLightWord = (word, highlight) => {
    const match = _.words(word?.toLowerCase(), RegExp(highlight?.toLowerCase()));
    const notMatch = _.replace(word.toLowerCase(), match, "");
    return (
      <View style={{flexDirection: "row"}}>
        <WLText style={{fontWeight: 'bold'}} text={match}/>
        <WLText text={notMatch}/>
      </View>
    );
  };

  return (
    <AnimatePresence>
      {showSugestions && suggestions.length > 0 &&
          <MotiView
              from={{
                opacity: 0.5,
              }}
              animate={{
                opacity: 1
              }}

              transition={{
                type:"timing",
                duration: 300,
              }}
              exit={{
                opacity: 0.5,
              }}

              style={styles.container}>
              <Pressable
                  onPress={onPress}
                  style={styles.backgroundSylte}/>
              <View
                  style={styles.contentWrapper}>
                  <TouchableOpacity onPress={() => onPressItem(suggestions[0])}>
                    {highLightWord(suggestions[0], searchText)}
                  </TouchableOpacity>
                  <View style={styles.brandsContainer}>
                      <View style={styles.brandsWrapper}>
                          <View
                              style={styles.brandsTagsWrapper}>
                            {categories?.map((item) => <View
                              key={item.name}
                              onTouchEnd={(e) => {
                                e.stopPropagation()
                              }}>
                              <TouchableOpacity
                                onPress={() => {
                                  onPressItem(item.name)
                                }}
                                style={styles.tagContainer}>
                                <WLText style={{fontStyle: 'oblique'}} text={'In '}/>
                                <WLText text={`${item.name}`}
                                        styleName={'NORMAL_MULTILINE'} ellipsizeAtLine={2} testID={`_TITLE`}/>
                              </TouchableOpacity>
                            </View>)}

                            {brands.map((item) => <View
                              key={item}
                              onTouchEnd={(e) => {
                                e.stopPropagation()
                              }}>
                              <TouchableOpacity
                                onPress={() => {
                                  onPressItem(item)
                                }}
                                style={styles.tagContainer}>
                                <WLText text={item}
                                        styleName={'NORMAL_MULTILINE'} ellipsizeAtLine={2} testID={`_TITLE`}/>
                              </TouchableOpacity>
                            </View>)}
                          </View>
                      </View>
                  </View>
                  <View>
                    {suggestions.length > 0 &&
                        <View style={{justifyContent: 'center',}}>
                          {suggestions.slice(1).map((item) => <View
                            key={item}
                            onTouchEnd={(e) => {
                              e.stopPropagation()
                            }}>
                            <TouchableOpacity
                              onPress={() => {
                                onPressItem(item)
                              }}
                              style={styles.itemStyle}>
                              {highLightWord(item, searchText)}
                            </TouchableOpacity>
                          </View>)}
                        </View>
                    }
                  </View>
              </View>
          </MotiView>
      }
    </AnimatePresence>
  )
}

WlAutocompleteSuggestionsComponent.propTypes = {
  showSugestions: PropTypes.bool,
  searchText: PropTypes.string,
  data: PropTypes.object,
  onPressItem: PropTypes.func,
  onPress: PropTypes.func,
  categories: PropTypes.array
};

the test code

import {render} from "@testing-library/react-native";
import React from "react";
import {
  WlAutocompleteSuggestionsComponent
} from "../wl-autocomplete-suggestions-component";

describe('WLAutocompleteSuggestions', ()=>{
  it('Renders Properly', ()=>{
    const {  getByTestId } = render(<WlAutocompleteSuggestionsComponent />);
    const titleText = getByTestId('_TITLE');
    expect(titleText).toBeTruthy()

  })
})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吝吻2025-01-20 15:07:00

尝试将 moti/.* 添加到 jest 配置中的 transformIgnorePatterns 字段(jest.config.js 文件或package.json 中的 jest 属性)
所以结果应该是这样的:

transformIgnorePatterns: ['node_modules/(?!(jest-)?@?react-native|moti/.*)']

Try to add moti/.* to transformIgnorePatterns field in your jest configuration (jest.config.js file or jest property in package.json)
So the result should looks like:

transformIgnorePatterns: ['node_modules/(?!(jest-)?@?react-native|moti/.*)']

难以启齿的温柔2025-01-20 15:07:00

谢谢@arseniy,它有效!

如果人们使用 TypeScript 和 Tamagui,这是我的配置 jest.config.js

// usefull to share ts config with `import { Stuff } from "@/components/Stuff";`
const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("./tsconfig");

// extract to an array to make it human readable
const packagesToTransform = [
  "react-native",
  "react-native-(.*)",
  "@react-native",
  "@react-native-community",
  "@react-navigation",
  "expo",
  "expo-(.*)",
  "react-native-svg",
  "@sentry/.*",
  "moti/.*"
];

/**
 * @type {import('@jest/types').Config.InitialOptions}
 * */
const config = {
  preset: "jest-expo",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
  modulePaths: ["<rootDir>/"],
  transformIgnorePatterns: [
    `node_modules/(?!(${packagesToTransform.join("|")})/)`
  ]
};

module.exports = config;

Thanks @arseniy it works!

here is my config jest.config.js if people are using TypeScript and Tamagui

// usefull to share ts config with `import { Stuff } from "@/components/Stuff";`
const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("./tsconfig");

// extract to an array to make it human readable
const packagesToTransform = [
  "react-native",
  "react-native-(.*)",
  "@react-native",
  "@react-native-community",
  "@react-navigation",
  "expo",
  "expo-(.*)",
  "react-native-svg",
  "@sentry/.*",
  "moti/.*"
];

/**
 * @type {import('@jest/types').Config.InitialOptions}
 * */
const config = {
  preset: "jest-expo",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json"],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
  modulePaths: ["<rootDir>/"],
  transformIgnorePatterns: [
    `node_modules/(?!(${packagesToTransform.join("|")})/)`
  ]
};

module.exports = config;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文