Add Some Tests
All checks were successful
CI / Build (push) Successful in 16s

This commit is contained in:
TheBrokenRail 2025-02-22 00:17:09 -05:00
parent fa7446151e
commit 27c4f4115b
5 changed files with 84 additions and 8 deletions

View File

@ -16,9 +16,9 @@ jobs:
# Dependencies
- name: Install Dependencies
run: npm ci
# Build
# Test
- name: Build
run: npm run build
run: npm test
# Lint
- name: Lint
run: npm run lint

View File

@ -1,5 +1,4 @@
// @ts-check
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import * as path from 'node:path';
@ -50,5 +49,13 @@ export default tseslint.config(
'build/',
'node_modules/'
]
},
{
files: [
'src/test/**/*'
],
rules: {
'@typescript-eslint/no-floating-promises': 'off'
}
}
);

View File

@ -4,9 +4,10 @@
"description": "",
"main": "build/index.js",
"scripts": {
"build": "tsc",
"build": "rm -rf build && tsc",
"start": "npm run build && node build/index.js",
"lint": "eslint ."
"lint": "eslint .",
"test": "npm run build && node --test build/test"
},
"author": "TheBrokenRail",
"license": "MIT",

View File

@ -34,6 +34,7 @@ export function syntaxError(message?: string): never {
throw new Error(extendErrorMessage(message, 'Syntax Error'));
}
// Convert 'int x' Into {type: 'int', name: 'x'}
const POINTER_TOKENS = ['*', '&'];
export function parseTypeAndName(piece: string) {
// Split On Last Space
const index = piece.lastIndexOf(' ');
@ -43,10 +44,10 @@ export function parseTypeAndName(piece: string) {
let name = piece.substring(index + 1);
let type = piece.substring(0, index);
// Move Asterisks From Name To Type
while (name.startsWith('*') || name.startsWith('&')) {
while (POINTER_TOKENS.some(x => name.startsWith(x))) {
const x = name.substring(0, 1);
name = name.substring(1);
if (!type.endsWith('*') && !type.endsWith('&')) {
if (!POINTER_TOKENS.some(x => type.endsWith(x))) {
type += ' ';
}
type += x;
@ -79,7 +80,7 @@ export function toUpperSnakeCase(str: string) {
}
// Convert 'int' To 'int ' But Leave 'int *' As Is
export function formatType(type: string) {
if (!type.endsWith('*') && !type.endsWith('&')) {
if (!POINTER_TOKENS.some(x => type.endsWith(x))) {
type += ' ';
}
return type;

67
src/test/common.ts Normal file
View File

@ -0,0 +1,67 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { formatType, parseTypeAndName, prependArg, toUpperSnakeCase } from '../common';
describe('Parsing Variable Declarations', () => {
const tests: [string, string, string, string][] = [
['Simple', 'int x', 'int', 'x'],
['Pointer', 'int *y', 'int *', 'y'],
['Ugly Pointer', 'int* z', 'int*', 'z'],
['Double Pointer', 'int **a', 'int **', 'a'],
['Ugly Double Pointer', 'int* *b', 'int**', 'b'],
['Reference', 'int &c', 'int &', 'c'],
['Reference-To-Pointer', 'int *&d', 'int *&', 'd']
];
for (const test of tests) {
it(test[0], () => {
const obj = parseTypeAndName(test[1]);
assert.strictEqual(obj.type, test[2]);
assert.strictEqual(obj.name, test[3]);
});
}
it('Invalid', () => {
assert.throws(() => {
parseTypeAndName('abc');
});
});
});
describe('Upper-Snake-Case', () => {
const tests: [string, string, string][] = [
['One Word', 'Hello', 'HELLO'],
['Two Words', 'HelloWorld', 'HELLO_WORLD'],
['Empty', '', ''],
['All Uppercase', 'HELLO', 'HELLO'],
['All Lowercase', 'hello', 'HELLO']
];
for (const test of tests) {
it(test[0], () => {
assert.strictEqual(toUpperSnakeCase(test[1]), test[2]);
});
}
});
describe('Formatting Types For Concatenation', () => {
const tests: [string, string, string][] = [
['Value', 'int', 'int '],
['Pointer', 'int *', 'int *'],
['Reference', 'int &', 'int &']
];
for (const test of tests) {
it(test[0], () => {
assert.strictEqual(formatType(test[1]), test[2]);
});
}
});
describe('Prepending Arguments To Functions', () => {
const tests: [string, string, string, string][] = [
['Empty', '()', 'int x', '(int x)'],
['Non-Empty', '(int x)', 'int y', '(int y, int x)']
];
for (const test of tests) {
it(test[0], () => {
assert.strictEqual(prependArg(test[1], test[2]), test[3]);
});
}
});