puty 0.0.6 โ 0.1.1
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 +20 -37
- package/package.json +9 -1
- package/src/index.js +7 -0
- package/src/puty.js +24 -3
- package/src/setup.js +11 -0
- package/src/utils.js +4 -0
- package/src/vitest-plugin.js +54 -0
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ Puty is ideal for testing pure functions - functions that always return the same
|
|
|
21
21
|
## Features
|
|
22
22
|
|
|
23
23
|
- ๐ Write tests in simple YAML format
|
|
24
|
+
- ๐ Zero-config Vitest plugin
|
|
24
25
|
- ๐ฆ Modular test organization with `!include` directive
|
|
25
26
|
- ๐ฏ Clear separation of test data and test logic
|
|
26
27
|
- ๐งช Mock support for testing functions with dependencies
|
|
@@ -44,17 +45,20 @@ Get up and running with Puty in just a few minutes!
|
|
|
44
45
|
### Step 1: Install Puty
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
|
-
npm install puty
|
|
48
|
+
npm install puty vitest
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
### Step 2:
|
|
51
|
+
### Step 2: Configure Vitest
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
Create `vitest.config.js`:
|
|
53
54
|
|
|
54
|
-
```
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
```js
|
|
56
|
+
import { defineConfig } from 'vitest/config'
|
|
57
|
+
import { putyPlugin } from 'puty/vitest'
|
|
58
|
+
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
plugins: [putyPlugin()]
|
|
61
|
+
})
|
|
58
62
|
```
|
|
59
63
|
|
|
60
64
|
### Step 3: Create a Function to Test
|
|
@@ -108,23 +112,22 @@ in: ['a']
|
|
|
108
112
|
out: 'A'
|
|
109
113
|
```
|
|
110
114
|
|
|
111
|
-
### Step 5:
|
|
112
|
-
|
|
113
|
-
Create `puty.test.js`:
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
import path from 'path'
|
|
117
|
-
import { setupTestSuiteFromYaml } from 'puty'
|
|
115
|
+
### Step 5: Add Test Script
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
Add a test script to your `package.json`:
|
|
120
118
|
|
|
121
|
-
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"scripts": {
|
|
122
|
+
"test": "vitest run"
|
|
123
|
+
}
|
|
124
|
+
}
|
|
122
125
|
```
|
|
123
126
|
|
|
124
127
|
### Step 6: Run Your Tests
|
|
125
128
|
|
|
126
129
|
```bash
|
|
127
|
-
|
|
130
|
+
npm test
|
|
128
131
|
```
|
|
129
132
|
|
|
130
133
|
You should see output like:
|
|
@@ -138,26 +141,6 @@ You should see output like:
|
|
|
138
141
|
|
|
139
142
|
๐ **That's it!** You've just created declarative tests using YAML instead of JavaScript.
|
|
140
143
|
|
|
141
|
-
### Recommended Vitest Configuration
|
|
142
|
-
|
|
143
|
-
To enable automatic test reruns when YAML test files change, create a `vitest.config.js` file in your project root:
|
|
144
|
-
|
|
145
|
-
```js
|
|
146
|
-
import { defineConfig } from 'vitest/config'
|
|
147
|
-
|
|
148
|
-
export default defineConfig({
|
|
149
|
-
test: {
|
|
150
|
-
forceRerunTriggers: [
|
|
151
|
-
'**/*.js',
|
|
152
|
-
'**/*.{test,spec}.yaml',
|
|
153
|
-
'**/*.{test,spec}.yml'
|
|
154
|
-
],
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
This configuration ensures that Vitest will re-run your tests whenever you modify either your JavaScript source files or your YAML test files.
|
|
160
|
-
|
|
161
144
|
## Usage
|
|
162
145
|
|
|
163
146
|
### Testing Functions
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "puty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A tooling function to test javascript functions and classes.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.js",
|
|
9
|
+
"./vitest": "./src/vitest-plugin.js",
|
|
10
|
+
"./setup": "./src/setup.js"
|
|
11
|
+
},
|
|
7
12
|
"files": [
|
|
8
13
|
"src"
|
|
9
14
|
],
|
|
@@ -24,5 +29,8 @@
|
|
|
24
29
|
},
|
|
25
30
|
"devDependencies": {
|
|
26
31
|
"vitest": "^3.2.1"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"vitest": ">=1.0.0"
|
|
27
35
|
}
|
|
28
36
|
}
|
package/src/index.js
CHANGED
|
@@ -4,9 +4,16 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { setupTestSuiteFromYaml } from "./puty.js";
|
|
7
|
+
import { putyPlugin } from "./vitest-plugin.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Main entry point function for discovering and setting up test suites from YAML files
|
|
10
11
|
* @see {@link setupTestSuiteFromYaml} for detailed documentation
|
|
11
12
|
*/
|
|
12
13
|
export { setupTestSuiteFromYaml };
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Vitest plugin for automatic YAML test file discovery
|
|
17
|
+
* @see {@link putyPlugin} for detailed documentation
|
|
18
|
+
*/
|
|
19
|
+
export { putyPlugin };
|
package/src/puty.js
CHANGED
|
@@ -92,6 +92,12 @@ const callNestedMethod = (obj, path, args = []) => {
|
|
|
92
92
|
*/
|
|
93
93
|
const extensions = [".test.yaml", ".test.yml", ".spec.yaml", ".spec.yml"];
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Registry of processed YAML test files to prevent duplicate registration
|
|
97
|
+
* @type {Set<string>}
|
|
98
|
+
*/
|
|
99
|
+
const processedFiles = new Set();
|
|
100
|
+
|
|
95
101
|
/**
|
|
96
102
|
* Parses YAML content containing multiple documents separated by '---' into a structured test configuration
|
|
97
103
|
* @param {string} yamlContent - Raw YAML content string to parse
|
|
@@ -506,8 +512,9 @@ export const injectFunctions = (module, originalTestConfig) => {
|
|
|
506
512
|
};
|
|
507
513
|
|
|
508
514
|
/**
|
|
509
|
-
* Discovers and sets up test suites from
|
|
515
|
+
* Discovers and sets up test suites from YAML test files
|
|
510
516
|
* @param {string} dirname - Directory path to search for YAML test files
|
|
517
|
+
* @param {string} [filename] - Optional specific filename to process (instead of scanning directory)
|
|
511
518
|
* @returns {Promise<void>} Promise that resolves when all test suites are set up
|
|
512
519
|
* @throws {Error} When YAML files cannot be parsed or modules cannot be imported
|
|
513
520
|
* @example
|
|
@@ -517,11 +524,25 @@ export const injectFunctions = (module, originalTestConfig) => {
|
|
|
517
524
|
* // Set up tests from a specific directory
|
|
518
525
|
* await setupTestSuiteFromYaml('./tests');
|
|
519
526
|
*
|
|
527
|
+
* // Set up a single YAML test file
|
|
528
|
+
* await setupTestSuiteFromYaml('./tests', 'math.test.yaml');
|
|
529
|
+
*
|
|
520
530
|
* // This will find all files matching: *.test.yaml, *.test.yml, *.spec.yaml, *.spec.yml
|
|
521
531
|
*/
|
|
522
|
-
export const setupTestSuiteFromYaml = async (dirname) => {
|
|
523
|
-
|
|
532
|
+
export const setupTestSuiteFromYaml = async (dirname, filename) => {
|
|
533
|
+
// If filename is provided, process only that file
|
|
534
|
+
const testYamlFiles = filename
|
|
535
|
+
? [path.join(dirname, filename)]
|
|
536
|
+
: traverseAllFiles(dirname, extensions);
|
|
537
|
+
|
|
524
538
|
for (const file of testYamlFiles) {
|
|
539
|
+
// Skip already processed files to prevent duplicate test registration
|
|
540
|
+
const absolutePath = path.resolve(file);
|
|
541
|
+
if (processedFiles.has(absolutePath)) {
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
processedFiles.add(absolutePath);
|
|
545
|
+
|
|
525
546
|
try {
|
|
526
547
|
const testConfig = parseWithIncludes(file);
|
|
527
548
|
const filepathRelativeToSpecFile = path.join(
|
package/src/setup.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Vitest setup file for puty - discovers and registers YAML test files
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { setupTestSuiteFromYaml } from "./puty.js";
|
|
6
|
+
|
|
7
|
+
// Use globalThis to ensure setup only runs once across all imports
|
|
8
|
+
if (!globalThis.__putySetupComplete) {
|
|
9
|
+
globalThis.__putySetupComplete = true;
|
|
10
|
+
await setupTestSuiteFromYaml(process.cwd());
|
|
11
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -88,6 +88,10 @@ export const traverseAllFiles = (startPath, extensions) => {
|
|
|
88
88
|
const results = [];
|
|
89
89
|
const files = fs.readdirSync(startPath);
|
|
90
90
|
for (const file of files) {
|
|
91
|
+
// Skip node_modules and hidden directories
|
|
92
|
+
if (file === "node_modules" || file.startsWith(".")) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
91
95
|
const filePath = path.join(startPath, file);
|
|
92
96
|
const stats = fs.statSync(filePath);
|
|
93
97
|
if (stats.isDirectory()) {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Vitest plugin for puty - enables YAML test files without manual setup
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Vitest plugin that automatically configures puty for YAML test discovery
|
|
9
|
+
* @returns {import('vite').Plugin} Vite/Vitest plugin
|
|
10
|
+
* @example
|
|
11
|
+
* // vitest.config.js
|
|
12
|
+
* import { defineConfig } from 'vitest/config'
|
|
13
|
+
* import { putyPlugin } from 'puty/vitest'
|
|
14
|
+
*
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* plugins: [putyPlugin()]
|
|
17
|
+
* })
|
|
18
|
+
*/
|
|
19
|
+
export function putyPlugin() {
|
|
20
|
+
return {
|
|
21
|
+
name: "vitest:puty",
|
|
22
|
+
|
|
23
|
+
config() {
|
|
24
|
+
return {
|
|
25
|
+
test: {
|
|
26
|
+
include: [
|
|
27
|
+
"**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}",
|
|
28
|
+
"**/*.{test,spec}.{yaml,yml}",
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
transform(code, id) {
|
|
35
|
+
// Only transform YAML test files
|
|
36
|
+
if (!/\.(test|spec)\.(yaml|yml)$/.test(id)) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const yamlDir = path.dirname(id);
|
|
41
|
+
|
|
42
|
+
// Generate a JS module that loads and runs this specific YAML file
|
|
43
|
+
const transformedCode = `
|
|
44
|
+
import { setupTestSuiteFromYaml } from 'puty';
|
|
45
|
+
await setupTestSuiteFromYaml('${yamlDir}', '${path.basename(id)}');
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
code: transformedCode,
|
|
50
|
+
map: null,
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|