@epikodelabs/testify 1.0.17 → 1.0.19
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/LICENSE +1 -1
- package/README.md +7 -24
- package/bin/jasmine +7 -7
- package/bin/testify +18 -7
- package/package.json +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# testify
|
|
2
2
|
|
|
3
|
-
A flexible test runner for Jasmine that supports multiple execution environments with built-in TypeScript compilation, hot module reloading, and code coverage.
|
|
3
|
+
A flexible test runner for the Jasmine testing framework that supports multiple execution environments with built-in TypeScript compilation, hot module reloading, and code coverage.
|
|
4
4
|
|
|
5
|
-
>
|
|
5
|
+
> ⚖️ “*testify doesn't mock the browser. It invites the browser into the courtroom and asks it to testify under oath.*”
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://github.com/epikodelabs/testify/actions/workflows/build.yml">
|
|
@@ -36,24 +36,6 @@ If testify helps you, please give it a star: https://github.com/epikodelabs/test
|
|
|
36
36
|
- 🎯 Interactive browser-based test reporter
|
|
37
37
|
- 🔧 VS Code debug integration for single-spec debugging
|
|
38
38
|
|
|
39
|
-
### Why "testify"?
|
|
40
|
-
|
|
41
|
-
Look, we'll be honest. Coming up with a testing library name in 2025 is like trying to find a good username on Twitter in 2010. Everything's taken. We considered:
|
|
42
|
-
|
|
43
|
-
- `test-runner` - Too generic (also taken)
|
|
44
|
-
- `jasmine-tester` - Too obvious (also taken)
|
|
45
|
-
- `vite-jasmine-runner` - Too long (and, you guessed it, taken)
|
|
46
|
-
- `super-mega-awesome-test-framework` - Too humble
|
|
47
|
-
|
|
48
|
-
So we landed on `testify` because:
|
|
49
|
-
1. Your tests should be able to testify about your code in court 🧑⚖️
|
|
50
|
-
2. It sounds vaguely spiritual, which you'll need when debugging flaky tests 🙏
|
|
51
|
-
3. The npm package name was actually available 🎉
|
|
52
|
-
4. It has the word "test" in it (we're nothing if not literal)
|
|
53
|
-
|
|
54
|
-
> **⚖️ The testify Promise**
|
|
55
|
-
> *testify doesn't mock the browser. It invites the browser into the courtroom and asks it to testify under oath.*
|
|
56
|
-
|
|
57
39
|
---
|
|
58
40
|
|
|
59
41
|
## 📦 Installation
|
|
@@ -355,6 +337,9 @@ Or manually add this configuration:
|
|
|
355
337
|
],
|
|
356
338
|
"program": "${workspaceFolder}/node_modules/@epikodelabs/testify/bin/jasmine",
|
|
357
339
|
"args": ["--spec", "${file}"],
|
|
340
|
+
"env": {
|
|
341
|
+
"TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json"
|
|
342
|
+
},
|
|
358
343
|
"cwd": "${workspaceFolder}",
|
|
359
344
|
"console": "integratedTerminal",
|
|
360
345
|
"skipFiles": ["<node_internals>/**"]
|
|
@@ -719,7 +704,7 @@ Coverage reports playing hide and seek? Make sure:
|
|
|
719
704
|
|
|
720
705
|
## 📜 License
|
|
721
706
|
|
|
722
|
-
MIT ©
|
|
707
|
+
MIT © 2026
|
|
723
708
|
|
|
724
709
|
---
|
|
725
710
|
|
|
@@ -727,13 +712,11 @@ MIT © 2025
|
|
|
727
712
|
|
|
728
713
|
- **Issues:** [GitHub Issues](https://github.com/epikodelabs/testify/issues)
|
|
729
714
|
- **Documentation:** [GitHub Wiki](https://github.com/epikodelabs/testify/wiki)
|
|
730
|
-
- **Changelog:** [CHANGELOG.md](./CHANGELOG.md)
|
|
731
715
|
|
|
732
716
|
---
|
|
733
717
|
|
|
734
718
|
<p align="center">
|
|
735
719
|
<strong>Get started</strong><br>
|
|
736
720
|
<a href="https://www.npmjs.com/package/@epikodelabs/testify">Install from NPM</a> •
|
|
737
|
-
<a href="https://github.com/epikodelabs/testify">View on GitHub</a>
|
|
738
|
-
<a href="https://forms.gle/YOUR_FEEDBACK_FORM_ID">Give Feedback</a>
|
|
721
|
+
<a href="https://github.com/epikodelabs/testify">View on GitHub</a>
|
|
739
722
|
</p>
|
package/bin/jasmine
CHANGED
|
@@ -68,12 +68,12 @@ const __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
|
68
68
|
const MAX_WIDTH = 63;
|
|
69
69
|
const ANSI_FULL_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
|
|
70
70
|
function wrapLine(text, width, indentation = 0, mode = "char") {
|
|
71
|
-
|
|
71
|
+
const normalized = text.replace(/\r?\n/g, "").replace(/[\uFEFF\xA0\t]/g, " ").replace(/\s{2,}/g, " ").trim();
|
|
72
72
|
const indent = " ".repeat(indentation);
|
|
73
73
|
const indentWidth = indent.length;
|
|
74
74
|
if (width <= indentWidth) width = indentWidth + 1;
|
|
75
75
|
const availableWidth = width - indentWidth;
|
|
76
|
-
return mode === "char" ? wrapByChar(
|
|
76
|
+
return mode === "char" ? wrapByChar(normalized, availableWidth, indent) : wrapByWord(normalized, availableWidth, indent);
|
|
77
77
|
}
|
|
78
78
|
function wrapByChar(text, available, indent) {
|
|
79
79
|
const lines = [];
|
|
@@ -186,8 +186,8 @@ class Logger {
|
|
|
186
186
|
// ─── REFORMAT (RESTORED) ─────────────────────────────────
|
|
187
187
|
reformat(text, opts) {
|
|
188
188
|
const { width, align = "left", padChar = " " } = opts;
|
|
189
|
-
const normalized = text.replace(/\r?\n/g, "
|
|
190
|
-
|
|
189
|
+
const normalized = text.replace(/\r?\n/g, "").replace(/[\uFEFF\xA0\t]/g, " ").replace(/\s{2,}/g, " ").trim();
|
|
190
|
+
let result = [];
|
|
191
191
|
let buf = "";
|
|
192
192
|
let vis = 0;
|
|
193
193
|
const tokens = normalized.split(
|
|
@@ -200,7 +200,7 @@ class Logger {
|
|
|
200
200
|
}
|
|
201
201
|
for (const ch of [...token]) {
|
|
202
202
|
if (vis >= width) {
|
|
203
|
-
|
|
203
|
+
result.push(this.applyPadding(buf, vis, width, align, padChar));
|
|
204
204
|
buf = "";
|
|
205
205
|
vis = 0;
|
|
206
206
|
}
|
|
@@ -209,9 +209,9 @@ class Logger {
|
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
211
|
if (buf) {
|
|
212
|
-
|
|
212
|
+
result.push(this.applyPadding(buf, vis, width, align, padChar));
|
|
213
213
|
}
|
|
214
|
-
return
|
|
214
|
+
return result;
|
|
215
215
|
}
|
|
216
216
|
applyPadding(text, visible, width, align, padChar) {
|
|
217
217
|
const pad = Math.max(0, width - visible);
|
package/bin/testify
CHANGED
|
@@ -1143,12 +1143,12 @@ class ConsoleReporter {
|
|
|
1143
1143
|
}
|
|
1144
1144
|
const ANSI_FULL_REGEX = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1B\\))/g;
|
|
1145
1145
|
function wrapLine(text, width, indentation = 0, mode = "char") {
|
|
1146
|
-
|
|
1146
|
+
const normalized = text.replace(/\r?\n/g, "").replace(/[\uFEFF\xA0\t]/g, " ").replace(/\s{2,}/g, " ").trim();
|
|
1147
1147
|
const indent = " ".repeat(indentation);
|
|
1148
1148
|
const indentWidth = indent.length;
|
|
1149
1149
|
if (width <= indentWidth) width = indentWidth + 1;
|
|
1150
1150
|
const availableWidth = width - indentWidth;
|
|
1151
|
-
return mode === "char" ? wrapByChar(
|
|
1151
|
+
return mode === "char" ? wrapByChar(normalized, availableWidth, indent) : wrapByWord(normalized, availableWidth, indent);
|
|
1152
1152
|
}
|
|
1153
1153
|
function wrapByChar(text, available, indent) {
|
|
1154
1154
|
const lines = [];
|
|
@@ -1261,8 +1261,8 @@ class Logger {
|
|
|
1261
1261
|
// ─── REFORMAT (RESTORED) ─────────────────────────────────
|
|
1262
1262
|
reformat(text, opts) {
|
|
1263
1263
|
const { width, align = "left", padChar = " " } = opts;
|
|
1264
|
-
const normalized = text.replace(/\r?\n/g, "
|
|
1265
|
-
|
|
1264
|
+
const normalized = text.replace(/\r?\n/g, "").replace(/[\uFEFF\xA0\t]/g, " ").replace(/\s{2,}/g, " ").trim();
|
|
1265
|
+
let result = [];
|
|
1266
1266
|
let buf = "";
|
|
1267
1267
|
let vis = 0;
|
|
1268
1268
|
const tokens = normalized.split(
|
|
@@ -1275,7 +1275,7 @@ class Logger {
|
|
|
1275
1275
|
}
|
|
1276
1276
|
for (const ch of [...token]) {
|
|
1277
1277
|
if (vis >= width) {
|
|
1278
|
-
|
|
1278
|
+
result.push(this.applyPadding(buf, vis, width, align, padChar));
|
|
1279
1279
|
buf = "";
|
|
1280
1280
|
vis = 0;
|
|
1281
1281
|
}
|
|
@@ -1284,9 +1284,9 @@ class Logger {
|
|
|
1284
1284
|
}
|
|
1285
1285
|
}
|
|
1286
1286
|
if (buf) {
|
|
1287
|
-
|
|
1287
|
+
result.push(this.applyPadding(buf, vis, width, align, padChar));
|
|
1288
1288
|
}
|
|
1289
|
-
return
|
|
1289
|
+
return result;
|
|
1290
1290
|
}
|
|
1291
1291
|
applyPadding(text, visible, width, align, padChar) {
|
|
1292
1292
|
const pad = Math.max(0, width - visible);
|
|
@@ -2947,6 +2947,17 @@ export async function runTests(reporter) {
|
|
|
2947
2947
|
process.exit(1);
|
|
2948
2948
|
});
|
|
2949
2949
|
|
|
2950
|
+
// Only attach SIGINT/SIGTERM handlers if running as CLI entry
|
|
2951
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
2952
|
+
function onExit(signal) {
|
|
2953
|
+
console.log(\`
|
|
2954
|
+
⚙️ Caught \${signal}. Cleaning up...\`);
|
|
2955
|
+
process.exit(0);
|
|
2956
|
+
}
|
|
2957
|
+
process.on('SIGINT', onExit);
|
|
2958
|
+
process.on('SIGTERM', onExit);
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2950
2961
|
(async function () {
|
|
2951
2962
|
try {
|
|
2952
2963
|
// Load jasmine-core from testify's own node_modules
|