@dannysir/js-te 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/cli.js +14 -96
- package/bin/utils/findFiles.js +56 -0
- package/bin/utils/transformFiles.js +34 -0
- package/constants.js +0 -5
- package/index.js +9 -89
- package/package.json +5 -5
- package/src/{tests.js → testManager.js} +4 -2
- package/utils/formatString.js +21 -0
package/README.md
CHANGED
package/bin/cli.js
CHANGED
|
@@ -1,108 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from 'fs';
|
|
4
3
|
import path from 'path';
|
|
5
|
-
import {transformSync} from '@babel/core';
|
|
6
4
|
import * as jsTe from '../index.js';
|
|
5
|
+
import {restoreFiles, transformFiles} from "./utils/transformFiles.js";
|
|
6
|
+
import {findAllSourceFiles, findTestFiles} from "./utils/findFiles.js";
|
|
7
7
|
import {green, red, yellow} from "../utils/consoleColor.js";
|
|
8
8
|
import {getTestResultMsg} from "../utils/makeMessage.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
let totalPassed = 0;
|
|
13
|
-
let totalFailed = 0;
|
|
14
|
-
const originalFiles = new Map();
|
|
15
|
-
|
|
16
|
-
Object.keys(jsTe).forEach(key => {
|
|
17
|
-
global[key] = jsTe[key];
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const transformFile = (filePath) => {
|
|
21
|
-
const originalCode = fs.readFileSync(filePath, 'utf-8');
|
|
22
|
-
originalFiles.set(filePath, originalCode);
|
|
23
|
-
|
|
24
|
-
const transformed = transformSync(originalCode, {
|
|
25
|
-
filename: filePath,
|
|
26
|
-
plugins: [babelTransformImport],
|
|
27
|
-
parserOpts: {
|
|
28
|
-
sourceType: BABEL.MODULE,
|
|
29
|
-
plugins: ['dynamicImport']
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
fs.writeFileSync(filePath, transformed.code);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const restoreFiles = () => {
|
|
37
|
-
for (const [filePath, originalCode] of originalFiles.entries()) {
|
|
38
|
-
try {
|
|
39
|
-
fs.writeFileSync(filePath, originalCode);
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error(red(`Failed to restore ${filePath}: ${error.message}`));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
originalFiles.clear();
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const findTestFiles = (dir) => {
|
|
48
|
-
const files = [];
|
|
49
|
-
|
|
50
|
-
const walk = (directory, inTestDir = false) => {
|
|
51
|
-
const items = fs.readdirSync(directory);
|
|
52
|
-
const dirName = path.basename(directory);
|
|
53
|
-
|
|
54
|
-
const isTestDir = dirName === PATH.TEST_DIRECTORY || inTestDir;
|
|
55
|
-
|
|
56
|
-
for (const item of items) {
|
|
57
|
-
if (item === PATH.NODE_MODULES) continue;
|
|
58
|
-
|
|
59
|
-
const fullPath = path.join(directory, item);
|
|
60
|
-
const stat = fs.statSync(fullPath);
|
|
61
|
-
|
|
62
|
-
if (stat.isDirectory()) {
|
|
63
|
-
walk(fullPath, isTestDir);
|
|
64
|
-
} else if (item.endsWith(PATH.TEST_FILE) || isTestDir) {
|
|
65
|
-
if (item.endsWith(PATH.JAVASCRIPT_FILE)) {
|
|
66
|
-
files.push(fullPath);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
walk(dir);
|
|
73
|
-
return files;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const findAllSourceFiles = (dir) => {
|
|
77
|
-
const files = [];
|
|
78
|
-
|
|
79
|
-
const walk = (directory) => {
|
|
80
|
-
const items = fs.readdirSync(directory);
|
|
81
|
-
|
|
82
|
-
for (const item of items) {
|
|
83
|
-
if (item === PATH.NODE_MODULES || item === PATH.BIN || item === PATH.TEST_DIRECTORY) continue;
|
|
84
|
-
|
|
85
|
-
const fullPath = path.join(directory, item);
|
|
86
|
-
const stat = fs.statSync(fullPath);
|
|
87
|
-
|
|
88
|
-
if (stat.isDirectory()) {
|
|
89
|
-
walk(fullPath);
|
|
90
|
-
} else if (item.endsWith(PATH.JAVASCRIPT_FILE) && !item.endsWith(PATH.TEST_FILE)) {
|
|
91
|
-
files.push(fullPath);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
walk(dir);
|
|
97
|
-
return files;
|
|
98
|
-
}
|
|
99
|
-
|
|
9
|
+
import {RESULT_TITLE} from "../constants.js";
|
|
10
|
+
import {run} from "../src/testRunner.js";
|
|
100
11
|
|
|
101
12
|
const main = async () => {
|
|
102
13
|
try {
|
|
14
|
+
let totalPassed = 0;
|
|
15
|
+
let totalFailed = 0;
|
|
16
|
+
|
|
17
|
+
Object.keys(jsTe).forEach(key => {
|
|
18
|
+
global[key] = jsTe[key];
|
|
19
|
+
});
|
|
20
|
+
|
|
103
21
|
const sourceFiles = findAllSourceFiles(process.cwd());
|
|
104
22
|
for (const file of sourceFiles) {
|
|
105
|
-
|
|
23
|
+
transformFiles(file);
|
|
106
24
|
}
|
|
107
25
|
|
|
108
26
|
const testFiles = findTestFiles(process.cwd());
|
|
@@ -112,10 +30,10 @@ const main = async () => {
|
|
|
112
30
|
for (const file of testFiles) {
|
|
113
31
|
console.log(`\n${yellow(file)}\n`);
|
|
114
32
|
|
|
115
|
-
|
|
33
|
+
transformFiles(file);
|
|
116
34
|
await import(path.resolve(file));
|
|
117
35
|
|
|
118
|
-
const {passed, failed} = await
|
|
36
|
+
const {passed, failed} = await run();
|
|
119
37
|
totalPassed += passed;
|
|
120
38
|
totalFailed += failed;
|
|
121
39
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import {PATH} from "../../constants.js";
|
|
4
|
+
|
|
5
|
+
export const findTestFiles = (dir) => {
|
|
6
|
+
const files = [];
|
|
7
|
+
|
|
8
|
+
const walk = (directory, inTestDir = false) => {
|
|
9
|
+
const items = fs.readdirSync(directory);
|
|
10
|
+
const dirName = path.basename(directory);
|
|
11
|
+
|
|
12
|
+
const isTestDir = dirName === PATH.TEST_DIRECTORY || inTestDir;
|
|
13
|
+
|
|
14
|
+
for (const item of items) {
|
|
15
|
+
if (item === PATH.NODE_MODULES) continue;
|
|
16
|
+
|
|
17
|
+
const fullPath = path.join(directory, item);
|
|
18
|
+
const stat = fs.statSync(fullPath);
|
|
19
|
+
|
|
20
|
+
if (stat.isDirectory()) {
|
|
21
|
+
walk(fullPath, isTestDir);
|
|
22
|
+
} else if (item.endsWith(PATH.TEST_FILE) || isTestDir) {
|
|
23
|
+
if (item.endsWith(PATH.JAVASCRIPT_FILE)) {
|
|
24
|
+
files.push(fullPath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
walk(dir);
|
|
31
|
+
return files;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const findAllSourceFiles = (dir) => {
|
|
35
|
+
const files = [];
|
|
36
|
+
|
|
37
|
+
const walk = (directory) => {
|
|
38
|
+
const items = fs.readdirSync(directory);
|
|
39
|
+
|
|
40
|
+
for (const item of items) {
|
|
41
|
+
if (item === PATH.NODE_MODULES || item === PATH.BIN || item === PATH.TEST_DIRECTORY) continue;
|
|
42
|
+
|
|
43
|
+
const fullPath = path.join(directory, item);
|
|
44
|
+
const stat = fs.statSync(fullPath);
|
|
45
|
+
|
|
46
|
+
if (stat.isDirectory()) {
|
|
47
|
+
walk(fullPath);
|
|
48
|
+
} else if (item.endsWith(PATH.JAVASCRIPT_FILE) && !item.endsWith(PATH.TEST_FILE)) {
|
|
49
|
+
files.push(fullPath);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
walk(dir);
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import {transformSync} from "@babel/core";
|
|
3
|
+
import {babelTransformImport} from "../../babelTransformImport.js";
|
|
4
|
+
import {BABEL} from "../../constants.js";
|
|
5
|
+
import {red} from "../../utils/consoleColor.js";
|
|
6
|
+
|
|
7
|
+
const originalFiles = new Map();
|
|
8
|
+
|
|
9
|
+
export const transformFiles = (filePath) => {
|
|
10
|
+
const originalCode = fs.readFileSync(filePath, 'utf-8');
|
|
11
|
+
originalFiles.set(filePath, originalCode);
|
|
12
|
+
|
|
13
|
+
const transformed = transformSync(originalCode, {
|
|
14
|
+
filename: filePath,
|
|
15
|
+
plugins: [babelTransformImport],
|
|
16
|
+
parserOpts: {
|
|
17
|
+
sourceType: BABEL.MODULE,
|
|
18
|
+
plugins: ['dynamicImport']
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
fs.writeFileSync(filePath, transformed.code);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const restoreFiles = () => {
|
|
26
|
+
for (const [filePath, originalCode] of originalFiles.entries()) {
|
|
27
|
+
try {
|
|
28
|
+
fs.writeFileSync(filePath, originalCode);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error(red(`Failed to restore ${filePath}: ${error.message}`));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
originalFiles.clear();
|
|
34
|
+
};
|
package/constants.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export const getErrorMsg = (expect, actual) => {
|
|
2
|
-
return `Expected ${JSON.stringify(expect)} but got ${JSON.stringify(actual)}`;
|
|
3
|
-
};
|
|
4
|
-
|
|
5
1
|
export const RESULT_TITLE = {
|
|
6
2
|
TESTS: 'Tests: ',
|
|
7
3
|
TOTAL : 'Total Result: '
|
|
@@ -46,5 +42,4 @@ export const PATH = {
|
|
|
46
42
|
TEST_FILE: '.test.js',
|
|
47
43
|
JAVASCRIPT_FILE: '.js',
|
|
48
44
|
BIN: 'bin',
|
|
49
|
-
|
|
50
45
|
};
|
package/index.js
CHANGED
|
@@ -1,94 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
getErrorMsg, RESULT_TITLE,
|
|
5
|
-
} from "./constants.js";
|
|
6
|
-
import {Tests} from "./src/tests.js";
|
|
7
|
-
import {green, red} from "./utils/consoleColor.js";
|
|
8
|
-
import {getTestResultMsg} from "./utils/makeMessage.js";
|
|
9
|
-
import {clearAllMocks} from "./src/mock/store.js";
|
|
1
|
+
import {testManager} from "./src/testManager.js";
|
|
2
|
+
import {clearAllMocks, isMocked, mock, unmock} from './src/mock/store.js';
|
|
3
|
+
import {expect} from "./src/expect.js";
|
|
10
4
|
|
|
11
|
-
const
|
|
5
|
+
export const test = (description, fn) => testManager.test(description, fn);
|
|
6
|
+
test.each = (cases) => testManager.testEach(cases);
|
|
12
7
|
|
|
13
|
-
export
|
|
8
|
+
export const describe = (suiteName, fn) => testManager.describe(suiteName, fn);
|
|
14
9
|
|
|
15
|
-
export const
|
|
16
|
-
test.each = (cases) => tests.testEach(cases);
|
|
10
|
+
export const beforeEach = (fn) => testManager.beforeEach(fn);
|
|
17
11
|
|
|
18
|
-
export
|
|
12
|
+
export {expect};
|
|
19
13
|
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
export const expect = (actual) => {
|
|
23
|
-
let value = actual;
|
|
24
|
-
|
|
25
|
-
const runArgFnc = (actual) => {
|
|
26
|
-
let value = actual;
|
|
27
|
-
if (typeof actual === 'function') {
|
|
28
|
-
value = actual();
|
|
29
|
-
}
|
|
30
|
-
return value;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
toBe(expected) {
|
|
35
|
-
value = runArgFnc(actual);
|
|
36
|
-
if (value !== expected) {
|
|
37
|
-
throw new Error(getErrorMsg(expected, value));
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
toEqual(expected) {
|
|
41
|
-
value = runArgFnc(actual);
|
|
42
|
-
if (JSON.stringify(value) !== JSON.stringify(expected)) {
|
|
43
|
-
throw new Error(getErrorMsg(expected, value));
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
toThrow(expected) {
|
|
47
|
-
try {
|
|
48
|
-
value = runArgFnc(actual);
|
|
49
|
-
} catch (e) {
|
|
50
|
-
if (!e.message.includes(expected)) {
|
|
51
|
-
throw new Error(getErrorMsg(expected, e.message));
|
|
52
|
-
} else return;
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
toBeTruthy() {
|
|
56
|
-
value = runArgFnc(actual);
|
|
57
|
-
if (!value) {
|
|
58
|
-
throw new Error(getErrorMsg(true, value));
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
toBeFalsy() {
|
|
62
|
-
value = runArgFnc(actual);
|
|
63
|
-
if (value) {
|
|
64
|
-
throw new Error(getErrorMsg(true, value));
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export const run = async () => {
|
|
71
|
-
let passed = DEFAULT_COUNT;
|
|
72
|
-
let failed = DEFAULT_COUNT;
|
|
73
|
-
|
|
74
|
-
for (const test of tests.getTests()) {
|
|
75
|
-
try {
|
|
76
|
-
await test.fn();
|
|
77
|
-
const directoryString = green(CHECK) + (test.path === '' ? EMPTY : test.path + DIRECTORY_DELIMITER) + test.description
|
|
78
|
-
console.log(directoryString);
|
|
79
|
-
passed++;
|
|
80
|
-
clearAllMocks();
|
|
81
|
-
} catch (error) {
|
|
82
|
-
const errorDirectory = red(CROSS) + test.path + test.description
|
|
83
|
-
console.log(errorDirectory);
|
|
84
|
-
console.log(red(` Error Message : ${error.message}`));
|
|
85
|
-
failed++;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
console.log(getTestResultMsg(RESULT_TITLE.TESTS, passed, failed));
|
|
90
|
-
|
|
91
|
-
tests.clearTests();
|
|
92
|
-
|
|
93
|
-
return {passed, failed};
|
|
94
|
-
}
|
|
14
|
+
export {mock, clearAllMocks, unmock, isMocked};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dannysir/js-te",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "JavaScript test library",
|
|
6
6
|
"main": "index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/dannysir/
|
|
19
|
+
"url": "git+https://github.com/dannysir/js-te-package.git"
|
|
20
20
|
},
|
|
21
21
|
"keywords": [
|
|
22
22
|
"javascript",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"files": [
|
|
29
29
|
"bin/",
|
|
30
|
-
"src/
|
|
30
|
+
"src/testManager.js",
|
|
31
31
|
"src/mock",
|
|
32
32
|
"utils/",
|
|
33
33
|
"index.js",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"author": "dannysir",
|
|
38
38
|
"license": "ISC",
|
|
39
39
|
"bugs": {
|
|
40
|
-
"url": "https://github.com/dannysir/
|
|
40
|
+
"url": "https://github.com/dannysir/js-te-package/issues"
|
|
41
41
|
},
|
|
42
|
-
"homepage": "https://github.com/dannysir/
|
|
42
|
+
"homepage": "https://github.com/dannysir/js-te-package#readme",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@babel/core": "^7.28.5",
|
|
45
45
|
"@babel/generator": "^7.28.5",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {DIRECTORY_DELIMITER} from "../constants.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class TestManager {
|
|
4
4
|
#tests = [];
|
|
5
5
|
#testDepth = [];
|
|
6
6
|
#beforeEachArr = [];
|
|
@@ -69,4 +69,6 @@ export class Tests {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const testManager = new TestManager();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {CHECK, CROSS, DIRECTORY_DELIMITER, EMPTY} from "../constants.js";
|
|
2
|
+
import {green, red} from "./consoleColor.js";
|
|
3
|
+
|
|
4
|
+
export const formatSuccessMessage = (test) => {
|
|
5
|
+
const pathString = test.path === '' ? EMPTY : test.path + DIRECTORY_DELIMITER;
|
|
6
|
+
return green(CHECK) + pathString + test.description;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const formatFailureMessage = (test, error) => {
|
|
10
|
+
const messages = [];
|
|
11
|
+
messages.push(red(CROSS) + test.path + test.description);
|
|
12
|
+
messages.push(red(` Error Message : ${error.message}`));
|
|
13
|
+
return messages.join('\n');
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getErrorMsg = (expect, actual) => {
|
|
17
|
+
return `Expected ${JSON.stringify(expect)} but got ${JSON.stringify(actual)}`;
|
|
18
|
+
};
|
|
19
|
+
export const getThrowErrorMsg = (expect) => {
|
|
20
|
+
return `Expected function to throw an error containing "${expect}", but it did not throw`;
|
|
21
|
+
};
|