-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: ability to read tests in ".jsx" and ".tsx" files #851
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,8 @@ | |
"typings" | ||
], | ||
"scripts": { | ||
"build": "tsc && npm run copy-static", | ||
"build": "tsc && npm run copy-static && npm run build-bundle -- --minify", | ||
"build-bundle": "esbuild ./src/bundle/index.ts --outdir=./build/src/bundle --bundle --format=cjs --platform=node --target=ES2021", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I build a bundle in order to not install all heavy babel deps in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should add it to the In watch script, we can either build the bundle once on startup, or make 2 separate scripts like I'm not sure how often we'll want to change (watch) bundle contents, so it's up to you to decide. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think about it, but it seemed to me that this file would rarely change. Anyway I add it to watch script. |
||
"copy-static": "copyfiles 'src/browser/client-scripts/*' build", | ||
"check-types": "tsc --project tsconfig.spec.json", | ||
"clean": "rimraf build/ *.tsbuildinfo", | ||
|
@@ -79,10 +80,16 @@ | |
"yallist": "3.1.1" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "7.24.1", | ||
"@babel/plugin-transform-modules-commonjs": "7.24.1", | ||
"@babel/plugin-transform-react-jsx": "7.23.4", | ||
"@babel/preset-react": "7.24.1", | ||
"@babel/preset-typescript": "7.24.1", | ||
"@commitlint/cli": "^19.0.3", | ||
"@commitlint/config-conventional": "^19.0.3", | ||
"@sinonjs/fake-timers": "10.3.0", | ||
"@swc/core": "1.3.40", | ||
"@types/babel__core": "7.20.5", | ||
"@types/bluebird": "3.5.38", | ||
"@types/chai": "4.3.4", | ||
"@types/chai-as-promised": "7.1.5", | ||
|
@@ -99,6 +106,7 @@ | |
"chai-as-promised": "7.1.1", | ||
"copyfiles": "2.4.1", | ||
"doctoc": "2.2.0", | ||
"esbuild": "0.20.2", | ||
"escape-string-regexp": "1.0.5", | ||
"eslint": "8.25.0", | ||
"eslint-config-gemini-testing": "2.8.0", | ||
|
@@ -107,6 +115,7 @@ | |
"jsdom": "^24.0.0", | ||
"jsdom-global": "3.0.2", | ||
"onchange": "7.1.0", | ||
"pirates": "4.0.6", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all deps installed in dev deps and used only through bundle |
||
"prettier": "2.8.4", | ||
"proxyquire": "1.8.0", | ||
"rimraf": "4.1.2", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const TRANSFORM_EXTENSIONS = [".jsx", ".cjsx", ".mjsx", ".tsx", ".ctsx", ".mtsx"]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extensions which should be transformed. I took various types of dependencies in which components can be described from this site - https://www.totaltypescript.com/concepts/mjs-cjs-mts-and-cts-extensions. |
||
export const JS_EXTENSION_RE = /^\.([cm]?[tj]sx?|json)$/; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. used in order to transform only javascript files and json. Omit all other extensions like |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./test-transformer"; | ||
export * from "./constants"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import * as nodePath from "node:path"; | ||
import * as babel from "@babel/core"; | ||
import { addHook } from "pirates"; | ||
import { TRANSFORM_EXTENSIONS, JS_EXTENSION_RE } from "./constants"; | ||
|
||
import type { NodePath, PluginObj, TransformOptions } from "@babel/core"; | ||
import type { ImportDeclaration } from "@babel/types"; | ||
|
||
export const setupTransformHook = (): VoidFunction => { | ||
const transformOptions: TransformOptions = { | ||
browserslistConfigFile: false, | ||
babelrc: false, | ||
configFile: false, | ||
compact: false, | ||
plugins: [ | ||
[ | ||
require("@babel/plugin-transform-react-jsx"), | ||
{ | ||
throwIfNamespace: false, | ||
runtime: "automatic", | ||
}, | ||
], | ||
require("@babel/plugin-transform-modules-commonjs"), | ||
[ | ||
(): PluginObj => ({ | ||
name: "ignore-imports", | ||
visitor: { | ||
ImportDeclaration(path: NodePath<ImportDeclaration>): void { | ||
const extname = nodePath.extname(path.node.source.value); | ||
|
||
if (extname && !extname.match(JS_EXTENSION_RE)) { | ||
path.remove(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here omit imports like |
||
} | ||
}, | ||
}, | ||
}), | ||
], | ||
], | ||
}; | ||
|
||
const revertTransformHook = addHook( | ||
(originalCode, filename) => { | ||
return babel.transform(originalCode, { filename, ...transformOptions })!.code as string; | ||
}, | ||
{ exts: TRANSFORM_EXTENSIONS }, | ||
); | ||
|
||
return revertTransformHook; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
export const setupTransformHook: () => VoidFunction = require("../bundle").setupTransformHook; | ||
export const TRANSFORM_EXTENSIONS: string[] = require("../bundle").TRANSFORM_EXTENSIONS; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest adding this comment to the code as well. To me it seems like typescript's project references would allow the use of imports here, but don't include those files in build. But probably not worth spending time on this right now, maybe just leave a todo in the comment. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import * as pirates from "pirates"; | ||
import sinon, { SinonStub } from "sinon"; | ||
import { setupTransformHook, TRANSFORM_EXTENSIONS } from "../../../src/test-reader/test-transformer"; | ||
|
||
describe("test-transformer", () => { | ||
const sandbox = sinon.createSandbox(); | ||
|
||
beforeEach(() => { | ||
sandbox.stub(pirates, "addHook").returns(sandbox.stub()); | ||
}); | ||
|
||
afterEach(() => sandbox.restore()); | ||
|
||
describe("setupTransformHook", () => { | ||
it("should return function to revert transformation", () => { | ||
const revertFn = sandbox.stub(); | ||
(pirates.addHook as SinonStub).returns(revertFn); | ||
|
||
assert.equal(setupTransformHook(), revertFn); | ||
}); | ||
|
||
describe("should transform", () => { | ||
TRANSFORM_EXTENSIONS.forEach(extName => { | ||
it(`component with extension: "${extName}"`, () => { | ||
let transformedCode; | ||
(pirates.addHook as SinonStub).callsFake(cb => { | ||
transformedCode = cb(`import "some${extName}"`); | ||
}); | ||
|
||
setupTransformHook(); | ||
|
||
assert.exists(transformedCode, `require("some${extName}")`); | ||
}); | ||
}); | ||
|
||
it("modules without extension", () => { | ||
let transformedCode; | ||
(pirates.addHook as SinonStub).callsFake(cb => { | ||
transformedCode = cb('import "some-module"'); | ||
}); | ||
|
||
setupTransformHook(); | ||
|
||
assert.exists(transformedCode, 'require("some-module")'); | ||
}); | ||
|
||
it(".json", () => { | ||
let transformedCode; | ||
(pirates.addHook as SinonStub).callsFake(cb => { | ||
transformedCode = cb('import "some.json"'); | ||
}); | ||
|
||
setupTransformHook(); | ||
|
||
assert.exists(transformedCode, 'require("some.json")'); | ||
}); | ||
}); | ||
|
||
describe("should not transform", () => { | ||
[".css", ".less", ".scss", ".jpg", ".png", ".woff"].forEach(extName => { | ||
it(`asset with extension: "${extName}"`, () => { | ||
let transformedCode; | ||
(pirates.addHook as SinonStub).callsFake(cb => { | ||
transformedCode = cb(`import "some${extName}"`); | ||
}); | ||
|
||
setupTransformHook(); | ||
|
||
assert.equal(transformedCode, '"use strict";'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
{ | ||
"extends": "./tsconfig.common.json", | ||
"include": ["src"], | ||
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts"], | ||
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts", "src/bundle"], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
"compilerOptions": { | ||
"outDir": "build" | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleted because it doesn't make sense anymore