Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ tsassert --verbose

The `project` option defaults to `./tsconfig.json`.

If you don't specify a file or pattern tsassert will use the `includes` from your `tsconfig.json`.
If you don't specify a file or pattern tsassert will use the `include` and `exclude` from your `tsconfig.json`.

If your `tsconfig.json` has an `exclude` option, these files will not be checked even if your manually provided glob matches them.

If you want to include a file that is excluded by your `tsconfig.json` you should extend the config, override the `exclude` property and provide this `tsconfig.json` as the `--project` argument e.g. `tsassert --project tsconfig.tsassert.json`.

Run `tsassert --help` for a full list of options.
Empty file added assertions/warn.ts
Empty file.
2 changes: 1 addition & 1 deletion package-lock.json

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

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@jakesidsmith/tsassert",
"version": "0.1.3",
"version": "0.2.0",
"description": "Check TypeScript types against assertion comments",
"publishConfig": {
"access": "public"
Expand All @@ -16,7 +16,7 @@
"lint-js": "tslint --project tsconfig.json",
"typecheck": "tsc --project tsconfig.json --noEmit",
"lint": "npm run prettier-check && npm run typecheck && npm run lint-js",
"tests": "./dist/cli.js assertions/pass.ts && if ./dist/cli.js assertions/fail.ts; then echo 'Failing tests passed' && exit 1; else echo 'All tests successfully passed or failed'; fi",
"tests": "./dist/cli.js assertions/pass.ts && if ./dist/cli.js assertions/fail.ts; then echo 'Failing tests passed' && exit 1; else echo 'All tests successfully passed or failed'; fi && ./dist/cli.js --project tsconfig.excludes.json && echo 'Failing files were successfully excluded'",
"test": "npm run lint && npm run dist && npm run tests",
"prepublishOnly": "npm test"
},
Expand Down
59 changes: 47 additions & 12 deletions src/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const assert = (tree: Tree) => {
return version();
}

logger.log('Checking type assertion comments', 'green');
logger.success('Checking type assertion comments');

const cwd = process.cwd();

Expand Down Expand Up @@ -48,31 +48,40 @@ const assert = (tree: Tree) => {
: '**/*.{ts,tsx}';

const includes = json.config?.include?.length
? json.config?.include?.map((include: string) =>
MATCHES_GLOB.test(include) ? include : path.join(include, extensions)
? json.config?.include?.map((pattern: string) =>
MATCHES_GLOB.test(pattern) ? pattern : path.join(pattern, extensions)
)
: globs?.length
? globs
: '*';

const excludes = json.config?.exclude?.length
? json.config?.exclude?.map((pattern: string) => `!${pattern}`)
: [];

if (tree.flags.verbose) {
logger.log(`Finding files matching:`);
logger.info('Finding files matching:');
logger.log(indent(includes.join('\n'), ' '));
logger.info('Excluding:');
logger.log(indent(excludes.join('\n'), ' '));
}

const sourceFileNames = globule.find(includes);
const sourceFileNames = globule.find([...globs, ...includes, ...excludes]);

if (!sourceFileNames.length) {
logger.error(`Could not find any source files matching:`);
return logger.error(indent(includes.join('\n'), ' '), true);
logger.error('Could not find any source files matching:');
logger.error(indent(includes.join('\n'), ' '));
logger.error('Excluding:');
return logger.error(indent(excludes.join('\n'), ' '), true);
}

if (tree.flags.verbose) {
logger.log('Found files:');
logger.info('Found files:');
logger.log(indent(sourceFileNames.join('\n'), ' '));

if (globs.length) {
logger.log(`Only checking files matching ${globs.join(' ')}`);
logger.info('Only checking files matching:');
logger.log(indent(globs.join('\n'), ' '));
}
}

Expand All @@ -86,10 +95,21 @@ const assert = (tree: Tree) => {
const sourceFiles = program.getSourceFiles();
const checker = program.getTypeChecker();

let filesChecked = 0;
let commentsChecked = 0;
const errors: string[] = [];

const checkTypes = (file: ts.SourceFile) => {
if (!globs.length || globule.isMatch(globs, file.fileName)) {
if (
(!globs.length || globule.isMatch(globs, file.fileName)) &&
(!excludes.length || globule.isMatch(excludes, file.fileName))
) {
filesChecked += 1;

if (tree.flags.verbose) {
logger.log(indent(file.fileName, ' '));
}

const lines = file.getFullText().split('\n');

const traverse = (node: ts.Node) => {
Expand All @@ -101,6 +121,7 @@ const assert = (tree: Tree) => {
const result = MATCHES_TRAILING_COMMENT.exec(line);

if (result && ts.isVariableDeclaration(node)) {
commentsChecked += 1;
const comment = result[1];
const lineNumber = lineIndex + 1;
const symbol = checker.getSymbolAtLocation(node.name);
Expand All @@ -126,16 +147,30 @@ const assert = (tree: Tree) => {
return errors;
};

if (tree.flags.verbose) {
logger.info('Checking files:');
}

sourceFiles.forEach(checkTypes);

if (errors.length) {
errors.forEach(error => {
logger.error(error);
});

return logger.error('Some files failed tsassert checks', true);
return logger.error('Some files failed tsassert checks.', true);
} else {
logger.log('All files passed tsassert checks', 'green');
if (!filesChecked) {
logger.warn(
'Could not find any matching files to check.\nRun with --verbose to see patterns that were checked.'
);
} else if (!commentsChecked) {
logger.warn(
'Could not find any type assertions in matched files.\nRun with --verbose to see patterns that were checked.'
);
} else {
logger.success('All files passed tsassert checks.');
}
}
};

Expand Down
20 changes: 18 additions & 2 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import * as chalk from 'chalk';

export const log = (input: string, color?: 'red' | 'green') => {
const _log = (input: string, color?: 'cyan' | 'red' | 'green' | 'yellow') => {
// tslint:disable-next-line:no-console
console.error(color ? chalk[color](input) : input);
};

export const log = (input: string) => {
_log(input);
};

export const info = (input: string) => {
_log(input, 'cyan');
};

export const success = (input: string) => {
_log(input, 'green');
};

export const warn = (input: string) => {
_log(input, 'yellow');
};

export const error = (input: string, exit?: boolean) => {
log(input, 'red');
_log(input, 'red');

if (exit) {
process.exit(1);
Expand Down
5 changes: 5 additions & 0 deletions tsconfig.excludes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["./assertions/"],
"exclude": ["./assertions/fail.ts"]
}