Skip to content

Commit

Permalink
Typescript (#2)
Browse files Browse the repository at this point in the history
* Added typescript outDir support for getOutputFilePath

* Compile if tsconfig is present

* Added a isTypescript flag

* Parse tsconfig fix

* Fix relative directory for mocks

* Updated test-ext logic

* Autoswitch ext for mocks

* Remove ext from imports

* Updated import code for typescript

* Refactor packaged external file

* Autoswitch dialect for PackagedExternalFile

* Check before trying to remove directory

* Autoswitch entrypoint

* Fixed mock offsets

* Typescript in AssignmentOperation

* MockImportBlock typescript support

* Autoswitch prettier parser

* Fixed mock import statements

* Fixed TestFileBlock test

* Updated documentation
  • Loading branch information
Ghost---Shadow committed Jun 7, 2020
1 parent bb69da8 commit ce95ca7
Show file tree
Hide file tree
Showing 31 changed files with 759 additions and 262 deletions.
59 changes: 31 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ npm i -g unit-test-recorder
5. Press `Q` or `Ctrl + C` key on the keyboard to safely stop the recording and your application and start generating the tests.
6. Run your favourite linter/prettier to clean up the generated test code.

### Typescript (beta)

`unit-test-recorder` will look for `tsconfig.json` in `pwd`. You can specifiy a differnt file using `--typescript-config=my-tsconfig.json`. This will make UTR automatically generate tests in typescript.

### Notes

* **IMPORTANT**: Serialization of JSONs in the process of recording may cause slowdown. The APIs may take considerably longer to execute. (2-10x)
Expand All @@ -33,24 +37,40 @@ npm i -g unit-test-recorder

Except `entrypoint` all are optional.

| Flag name | Description |
| --------- | ------------ |
| entrypoint (positional) | Path to entrypoint of your application |
| --only | Run only on these files (relative path, comma separated, supports javascript RegExp) |
| --except | Dont run on these files (relative path, comma separated, supports javascript RegExp) |
| --whitelist | Path to `whitelist.json` |
| --max-tests | Maximum number of generated tests per function. Type -1 for infinity. Default 5. |
| --output-dir | The directory in which the tests would be written to. |
| --test-ext | Extension for test files (spec.js/test.ts) |
| --size-limit | Objects larger than this limit will be moved to a different file |
| --max-stack-depth | Properties of a JSON, at a depth higher than this, will not be recorded. Default 7. |
| Flag name | Description | Default |
| --------- | ------------ | ------------ |
| entrypoint (positional) | Path to entrypoint of your application | None (Required) |
| --only | Run only on these files (relative path, comma separated, supports javascript RegExp) | undefined |
| --except | Dont run on these files (relative path, comma separated, supports javascript RegExp) | undefined |
| --whitelist | Path to `whitelist.json` | `./whitelist.json` |
| --typescript-config | Path to typescript config | `./tsconfig.json` |
| --max-tests | Maximum number of generated tests per function. Type -1 for infinity. | 5 |
| --output-dir | The directory in which the tests would be written to. | `./` |
| --test-ext | Extension for test files (spec/test) | test |
| --size-limit | Objects larger than this limit will be moved to a different file | 500 |
| --max-stack-depth | Properties of a JSON, at a depth higher than this, will not be recorded. | 7 |

### Environment variables

| Environment variable name | Description |
| --------- | ------------ |
| UTR_EXPERIMENTAL_ALS | Set this flag to use `AsyncLocalStorage` instead of `cls-hooked`. (Experimental, requires nodejs `v13.10+`) |

## Features

* Pure functions
* Dependency injections
* Mocks
* Typescript (beta)

## Planned features

* JSX
* class methods
* function methods
* Better typescript support
* Higher order functions

## Mechanism

Lets take this function as an example
Expand Down Expand Up @@ -109,23 +129,6 @@ describe('fileName', () => {
})
```

## Planned features

* Higher order functions
* class methods and JSX
* function methods
* Better typescript support (partial available)

## Typescript (work in progress)

* Make sure you have `ts-node` installed.
* Run using `ts-unit-test-recorder` instead of `unit-test-recorder`

If that doesnt work

* Compile typescript into javascript
* Run `unit-test-recorder dist/index.js --output-dir=test --test-ext=test.ts`

## Troubleshooting

* UTR is still early in development and may be unstable. Users are recommended to use the `--only` flag to run UTR on a few files at a time.
Expand Down
48 changes: 26 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
"name": "unit-test-recorder",
"bin": {
"unit-test-recorder": "src/index.js",
"ts-unit-test-recorder": "src/index.ts"
"unit-test-recorder": "src/index.js"
},
"version": "0.1.1",
"version": "0.2.0",
"description": "A cli tool records usage and generates unit tests",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -56,6 +55,8 @@
"lodash": "^4.17.15",
"mkdirp": "^1.0.4",
"prettier": "^1.19.1",
"rimraf": "^3.0.2",
"typescript": "^3.9.5",
"uuid": "^8.0.0",
"yargs": "^15.3.1"
},
Expand Down
3 changes: 1 addition & 2 deletions src/cli/generation.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const writeFileAsync = promisify(fs.writeFile);
const writeTestAndExternalData = async ({ testObj, packagedArguments }) => {
console.log('Writing test for: ', testObj.filePath);
mkdirp.sync(path.dirname(testObj.filePath));
const { testExt } = packagedArguments;
const testFileName = getTestFileNameForFile(testObj.filePath, testExt);
const testFileName = getTestFileNameForFile(testObj.filePath, packagedArguments);
const testFilePromise = writeFileAsync(testFileName, testObj.fileString);
const externalDataPromises = testObj.externalData.map((ed) => {
console.log('Creating dir:', path.dirname(ed.filePath));
Expand Down
19 changes: 16 additions & 3 deletions src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ const { argv } = require('yargs')
.describe('whitelist', 'Specify the path to whitelist json')
.alias('w', 'whitelist')

.default('typescript-config', './tsconfig.json')
.describe('typescript-config', 'Specify the path to tsconfig.json (ignore if not typescript)')
.alias('tc', 'typescript-config')

.default('max-tests', '5')
.describe('max-tests', 'Maximum number of generated tests per function. Type -1 for infinity')
.alias('t', 'max-tests')
Expand All @@ -18,8 +22,8 @@ const { argv } = require('yargs')
.describe('output-dir', 'The directory in which the tests would be written to.')
.alias('o', 'output-dir')

.default('test-ext', 'test.js')
.describe('test-ext', 'Extension for test files (spec.js/test.ts)')
.default('test-ext', 'test')
.describe('test-ext', 'Extension for test files (spec/test)')

.default('size-limit', 500)
.describe('size-limit', 'Objects larger than this limit will be moved to a different file')
Expand All @@ -38,12 +42,13 @@ const { argv } = require('yargs')
.describe('record-stub-params', 'Record the arguments passed as parameters to stubs (Debugging only)')

.boolean(['d']); // Debug
const { compileAndGetOutputDir } = require('./utils');

const { instrumentAllFiles } = require('./instrumentation');
const { generateAllTests } = require('./generation');

// Process and package arguments
const entryPoint = argv._[0];
const entryPointArgument = argv._[0];
const maxTestsPerFunction = parseInt(argv.maxTests, 10) || -1;
const debug = argv.d;
const {
Expand All @@ -52,9 +57,15 @@ const {
sizeLimit,
recordStubParams,
maxStackDepth,
typescriptConfig,
} = argv;

const exceptFiles = typeof argv.except === 'string' ? argv.except.split(',') : [];
const onlyFiles = typeof argv.only === 'string' ? argv.only.split(',') : [];
const tsBuildDir = compileAndGetOutputDir(typescriptConfig);

const entryPoint = path.join(tsBuildDir || './', entryPointArgument).replace(/\.ts$/, '.js');

const packagedArguments = {
entryPoint,
maxTestsPerFunction,
Expand All @@ -66,6 +77,8 @@ const packagedArguments = {
onlyFiles,
recordStubParams,
maxStackDepth,
tsBuildDir,
isTypescript: !!tsBuildDir,
};

// Set the environment variable flag so that recorder can pick it up
Expand Down
30 changes: 30 additions & 0 deletions src/cli/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const cp = require('child_process');
const fs = require('fs');
const ts = require('typescript');

const rimraf = require('rimraf');

const compileAndGetOutputDir = (typescriptConfig) => {
if (fs.existsSync(typescriptConfig)) {
console.log(`Typescript config found at ${typescriptConfig}`);
const contents = fs.readFileSync(typescriptConfig).toString();
const { config, error } = ts.parseConfigFileTextToJson(typescriptConfig, contents);

if (error) throw new Error(error);

const tsBuildDir = config.compilerOptions.outDir;
if (fs.existsSync(tsBuildDir)) {
console.log('Purging build directory');
rimraf.sync(tsBuildDir);
}
console.log('Recompiling');
cp.execSync('tsc');
console.log('Compiled');
return tsBuildDir;
}
return null;
};

module.exports = {
compileAndGetOutputDir,
};
Loading

0 comments on commit ce95ca7

Please sign in to comment.