@dannysir/js-te 0.1.0 → 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 CHANGED
@@ -44,6 +44,11 @@ package.json에 추가.
44
44
  npm test
45
45
  ```
46
46
 
47
+ ### 예시 출력 화면
48
+
49
+ <p align='center'>
50
+ <img width="585" height="902" alt="스크린샷 2025-11-20 오후 12 22 27" src="https://github.com/user-attachments/assets/3d087a61-cc44-4f5b-8a2f-efd5f15c12b7" />
51
+ </p>
47
52
 
48
53
  # API
49
54
 
@@ -319,7 +324,7 @@ export const random = () => Math.random();
319
324
 
320
325
  ## 링크
321
326
 
322
- - [GitHub](https://github.com/dannysir/Js-Te)
327
+ - [GitHub](https://github.com/dannysir/js-te-package)
323
328
 
324
329
  ## 만든 이유
325
330
 
@@ -327,4 +332,4 @@ export const random = () => Math.random();
327
332
 
328
333
  ## 라이선스
329
334
 
330
- ISC
335
+ ISC
package/bin/cli.js CHANGED
@@ -1,123 +1,55 @@
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';
7
- import {green, yellow} from "../utils/consoleColor.js";
5
+ import {restoreFiles, transformFiles} from "./utils/transformFiles.js";
6
+ import {findAllSourceFiles, findTestFiles} from "./utils/findFiles.js";
7
+ import {green, red, yellow} from "../utils/consoleColor.js";
8
8
  import {getTestResultMsg} from "../utils/makeMessage.js";
9
- import {BABEL, PATH, RESULT_TITLE} from "../constants.js";
10
- import { babelTransformImport } from '../babelTransformImport.js';
9
+ import {RESULT_TITLE} from "../constants.js";
10
+ import {run} from "../src/testRunner.js";
11
11
 
12
- let totalPassed = 0;
13
- let totalFailed = 0;
14
- const originalFiles = new Map();
12
+ const main = async () => {
13
+ try {
14
+ let totalPassed = 0;
15
+ let totalFailed = 0;
15
16
 
16
- Object.keys(jsTe).forEach(key => {
17
- global[key] = jsTe[key];
18
- });
17
+ Object.keys(jsTe).forEach(key => {
18
+ global[key] = jsTe[key];
19
+ });
19
20
 
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']
21
+ const sourceFiles = findAllSourceFiles(process.cwd());
22
+ for (const file of sourceFiles) {
23
+ transformFiles(file);
30
24
  }
31
- });
32
-
33
- fs.writeFileSync(filePath, transformed.code);
34
- };
35
-
36
- const restoreFiles = () => {
37
- for (const [filePath, originalCode] of originalFiles.entries()) {
38
- fs.writeFileSync(filePath, originalCode);
39
- }
40
- };
41
25
 
42
- const findTestFiles = (dir) => {
43
- const files = [];
26
+ const testFiles = findTestFiles(process.cwd());
44
27
 
45
- const walk = (directory, inTestDir = false) => {
46
- const items = fs.readdirSync(directory);
47
- const dirName = path.basename(directory);
28
+ console.log(`\nFound ${green(testFiles.length)} test file(s)`);
48
29
 
49
- const isTestDir = dirName === PATH.TEST_DIRECTORY || inTestDir;
30
+ for (const file of testFiles) {
31
+ console.log(`\n${yellow(file)}\n`);
50
32
 
51
- for (const item of items) {
52
- if (item === PATH.NODE_MODULES) continue;
33
+ transformFiles(file);
34
+ await import(path.resolve(file));
53
35
 
54
- const fullPath = path.join(directory, item);
55
- const stat = fs.statSync(fullPath);
56
-
57
- if (stat.isDirectory()) {
58
- walk(fullPath, isTestDir);
59
- } else if (item.endsWith(PATH.TEST_FILE) || isTestDir) {
60
- if (item.endsWith(PATH.JAVASCRIPT_FILE)) {
61
- files.push(fullPath);
62
- }
63
- }
36
+ const {passed, failed} = await run();
37
+ totalPassed += passed;
38
+ totalFailed += failed;
64
39
  }
65
- }
66
-
67
- walk(dir);
68
- return files;
69
- }
70
40
 
71
- const findAllSourceFiles = (dir) => {
72
- const files = [];
41
+ console.log(getTestResultMsg(RESULT_TITLE.TOTAL, totalPassed, totalFailed));
73
42
 
74
- const walk = (directory) => {
75
- const items = fs.readdirSync(directory);
43
+ return totalFailed > 0 ? 1 : 0;
76
44
 
77
- for (const item of items) {
78
- if (item === PATH.NODE_MODULES || item === PATH.BIN || item === PATH.TEST_DIRECTORY) continue;
79
-
80
- const fullPath = path.join(directory, item);
81
- const stat = fs.statSync(fullPath);
82
-
83
- if (stat.isDirectory()) {
84
- walk(fullPath);
85
- } else if (item.endsWith(PATH.JAVASCRIPT_FILE) && !item.endsWith(PATH.TEST_FILE)) {
86
- files.push(fullPath);
87
- }
88
- }
45
+ } catch (error) {
46
+ console.log(red('\n✗ Test execution failed'));
47
+ console.log(red(` Error: ${error.message}\n`));
48
+ return 1;
49
+ } finally {
50
+ restoreFiles();
89
51
  }
52
+ };
90
53
 
91
- walk(dir);
92
- return files;
93
- }
94
-
95
- const sourceFiles = findAllSourceFiles(process.cwd());
96
-
97
- for (const file of sourceFiles) {
98
- transformFile(file);
99
- }
100
-
101
- const testFiles = findTestFiles(process.cwd());
102
-
103
- console.log(`\nFound ${green(testFiles.length)} test file(s)`);
104
-
105
- for (const file of testFiles) {
106
- console.log(`\n${yellow(file)}\n`);
107
-
108
- transformFile(file);
109
-
110
- await import(path.resolve(file));
111
-
112
- const {passed, failed} = await jsTe.run();
113
- totalPassed += passed;
114
- totalFailed += failed;
115
- }
116
-
117
- restoreFiles();
118
-
119
- console.log(getTestResultMsg(RESULT_TITLE.TOTAL, totalPassed, totalFailed));
120
-
121
- if (totalFailed > 0) {
122
- process.exit(1);
123
- }
54
+ const exitCode = await main();
55
+ process.exit(exitCode);
@@ -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
- CHECK,
3
- CROSS, DEFAULT_COUNT, DIRECTORY_DELIMITER, EMPTY,
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 tests = new Tests();
5
+ export const test = (description, fn) => testManager.test(description, fn);
6
+ test.each = (cases) => testManager.testEach(cases);
12
7
 
13
- export { mock, clearAllMocks, unmock, isMocked } from './src/mock/store.js';
8
+ export const describe = (suiteName, fn) => testManager.describe(suiteName, fn);
14
9
 
15
- export const test = (description, fn) => tests.test(description, fn);
16
- test.each = (cases) => tests.testEach(cases);
10
+ export const beforeEach = (fn) => testManager.beforeEach(fn);
17
11
 
18
- export const describe = (suiteName, fn) => tests.describe(suiteName, fn);
12
+ export {expect};
19
13
 
20
- export const beforeEach = (fn) => tests.beforeEach(fn);
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}`));
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.0",
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/Js-Te.git"
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/tests.js",
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/Js-Te/issues"
40
+ "url": "https://github.com/dannysir/js-te-package/issues"
41
41
  },
42
- "homepage": "https://github.com/dannysir/Js-Te#readme",
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
- export class Tests {
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
+ };