Files
privacy.sexy/tests/unit/application/collections/NoUnintentedInlining.spec.ts
undergroundwires 2f06043559 Bump Node.js environment to 18.x
- Bump Node.js to version 18. This change is necessary as Node.js v16
  will reach end-of-life on 2023-09-11. It also ensure compatibility
  with dependencies requiring minimum of Node.js v18, such as `vite`,
  `@vitejs`plugin-legacy` and `icon-gen`.
- Bump `setup-node` action to v4.
- Recommend using the `nvm` tool for managing Node.js versions in the
  documentation.
- Update documentation to point to code reference for required Node.js
  version. This removes duplication of information, and keeps the code
  as single source of truth for required Node.js version.
- Refactor code to adopt the `node:` protocol for Node API imports as
  per Node.js 18 standards. This change addresses ambiguities and aligns
  with Node.js best practices (nodejs/node#38343). Currently, there is
  no ESLint rule to enforce this protocol, as noted in
  import-js/eslint-plugin-import#2717.
- Replace `cross-fetch` dependency with the native Node.js fetch API
  introduced in Node.js 18. Adjust type casting for async iterable read
  streams to align with the latest Node.js APIs, based on discussions in
  DefinitelyTyped/DefinitelyTyped#65542.
2023-12-28 11:57:38 +01:00

82 lines
2.7 KiB
TypeScript

import { readdirSync, readFileSync } from 'node:fs';
import { resolve, join, basename } from 'node:path';
import { describe, it, expect } from 'vitest';
import { formatAssertionMessage } from '@tests/shared/FormatAssertionMessage';
/*
A common mistake when working with yaml files to forget mentioning that a value should
be interpreted as multi-line string using "|".
E.g.
```
code: |-
echo Hello
echo World
```
If "|" is missing then the code is inlined like `echo Hello echo World``, which can be
unintended. This test checks for similar issues in collection yaml files.
These tests can be considered as "linter" more than "unit-test" and therefore can lead
to false-positives.
*/
describe('collection files to have no unintended inlining', () => {
// arrange
const testCases = createTestCases('src/application/collections/');
for (const testCase of testCases) {
it(`${testCase.name}`, async () => {
// act
const lines = await findBadLineNumbers(testCase.content);
// assert
expect(lines).to.be.have.lengthOf(0, formatAssertionMessage([
'Did you intend to have multi-lined string in lines: ',
lines.map(((line) => line.toString())).join(', '),
]));
});
}
});
async function findBadLineNumbers(fileContent: string): Promise<number[]> {
return [
...findLineNumbersEndingWith(fileContent, 'revertCode:'),
...findLineNumbersEndingWith(fileContent, 'code:'),
];
}
function findLineNumbersEndingWith(content: string, ending: string): number[] {
sanityCheck(content, ending);
return content
.split(/\r\n|\r|\n/)
.map((line, index) => ({ text: line, index }))
.filter((line) => line.text.trim().endsWith(ending))
.map((line) => line.index + 1 /* first line is 1, not 0 */);
}
function sanityCheck(content: string, ending: string): void {
if (!content) {
throw new Error('File content is empty, is the file loaded correctly?');
}
if (!content.includes(ending)) {
throw new Error(
`File does not contain string "${ending}" string at all.`
+ `Did the word "${ending}" change? Or is this sanity check wrong?`,
);
}
}
interface ITestCase {
name: string;
content: string;
}
function createTestCases(collectionsDirFromRoot: string): ITestCase[] {
const collectionsDir = resolve(`./${collectionsDirFromRoot}`);
const fileNames = readdirSync(collectionsDir);
if (fileNames.length === 0) {
throw new Error(`Could not find any collection in ${collectionsDir}`);
}
const collectionFilePaths = fileNames
.filter((name) => name.endsWith('.yaml'))
.map((name) => join(collectionsDir, name));
return collectionFilePaths.map((path) => ({
name: basename(path),
content: readFileSync(path, 'utf-8'),
}));
}