使用Jest与Typescript + preact

时间:2017-07-27 21:09:59

标签: typescript babel create-react-app jest preact

在测试中将JSX转换为h()的问题。所有配置文件与create-react-app类似,不包括TypeScriptpreact的更改

我通过create-react-app my-app --script=react-scripts-ts创建应用程序 - 用于TypeScript项目。然后弹出并将react更改为preact(不要使用preact-compat)。

要迁移到preact我要将package.json添加到babel.plugins section新插件["babel-plugin-transform-react-jsx", { pragma: "h"}]中 - 以便将<JSX />转换为h(JSX)函数调用,而不是默认React.createElement(JSX)(迁移指南https://preactjs.com/guide/switching-to-preact)。

这很好用。

但是测试具有不同的转换<JSX />配置:它转换为React.createElement(JSX)是默认的。在测试中我收到错误ReferenceError: React is not defined at Object.<anonymous> (src/Linkify/Linkify.test.tsx:39:21)。如果我在测试和测试文件中手动将<JSX />更改为h(SomeComponent) - 它可以正常工作。

如何将<JSX />转换为h(JSX)进行测试?

// typescriptTransform.js
// Copyright 2004-present Facebook. All Rights Reserved.

'use strict';

const fs = require('fs');
const crypto = require('crypto');
const tsc = require('typescript');
const tsconfigPath = require('app-root-path').resolve('/tsconfig.json');
const THIS_FILE = fs.readFileSync(__filename);

let compilerConfig = {
  module: tsc.ModuleKind.CommonJS,
  jsx: tsc.JsxEmit.React,
};

if (fs.existsSync(tsconfigPath)) {
  try {
    const tsconfig = tsc.readConfigFile(tsconfigPath).config;

    if (tsconfig && tsconfig.compilerOptions) {
      compilerConfig = tsconfig.compilerOptions;
    }
  } catch (e) {
    /* Do nothing - default is set */
  }
}

module.exports = {
  process(src, path, config, options) {
    if (path.endsWith('.ts') || path.endsWith('.tsx')) {
      let compilerOptions = compilerConfig;
      if (options.instrument) {
        // inline source with source map for remapping coverage
        compilerOptions = Object.assign({}, compilerConfig);
        delete compilerOptions.sourceMap;
        compilerOptions.inlineSourceMap = true;
        compilerOptions.inlineSources = true;
        // fix broken paths in coverage report if `.outDir` is set
        delete compilerOptions.outDir;
      }

      const tsTranspiled = tsc.transpileModule(src, {
        compilerOptions: compilerOptions,
        fileName: path,
      });
      return tsTranspiled.outputText;
    }
    return src;
  },
  getCacheKey(fileData, filePath, configStr, options) {
    return crypto
      .createHash('md5')
      .update(THIS_FILE)
      .update('\0', 'utf8')
      .update(fileData)
      .update('\0', 'utf8')
      .update(filePath)
      .update('\0', 'utf8')
      .update(configStr)
      .update('\0', 'utf8')
      .update(JSON.stringify(compilerConfig))
      .update('\0', 'utf8')
      .update(options.instrument ? 'instrument' : '')
      .digest('hex');
  },
};

测试样本:

import { h, render } from 'preact';
import Linkify from './Linkify';

it('renders without crashing', () => {
  const div = document.createElement('div');
  render(<Linkify children={'text'} />, div);
});

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。

我在$my_keys = array_keys($Arr[0]); // ---- This prevents PDO SQL Injection $stmt=$pdo->prepare("DESC my_table"); $stmt->execute(); $whitelist_columns=$stmt->fetchAll(PDO::FETCH_COLUMN); foreach($my_keys as $key){ if(!array_search($key,$whitelist_columns)){ echo "ERROR!"; } } // ---- End of prevention $field_names = implode(",", $my_keys); // build column list /** @JBH this foreach is needed otherwise the $q_markers will result not PDO placeholders like. If this is missing, the query inserts all "" values, no matter if you'll adopt bindValue or bindParam**/ foreach($my_keys as &$key){ $key = ":".$key; } $q_markers = implode(",", $my_keys); // build PDO value markers $stmt = $pdo->prepare("INSERT INTO my_table (".$field_names.") VALUES (".$q_markers.")"); foreach($Arr as $key => $val){ foreach($val as $bind_marker => &$bind_val){ /** @ JBH Without "&" here, it will work only bindValue. Instead with "&", they work both bindParam and bindValue **/ $stmt->bindParam($bind_marker, $bind_val); } $stmt->execute(); } 部分babel.plugins中错了 - 它没有使用。实际上,此pragma使用new plugin ["babel-plugin-transform-react-jsx", { pragma: "h"}] - tsconfig.json

但是,该指令并未在"jsxFactory": "h"中使用。

我扩展了编译器选项

typescriptTransform.js

希望它会有用。