puty 0.0.6 โ†’ 0.1.0

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
@@ -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: Setup Your Project
51
+ ### Step 2: Configure Vitest
51
52
 
52
- Ensure your `package.json` has ES modules enabled:
53
+ Create `vitest.config.js`:
53
54
 
54
- ```json
55
- {
56
- "type": "module"
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: Create Test Runner
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
- const __dirname = path.dirname(new URL(import.meta.url).pathname)
117
+ Add a test script to your `package.json`:
120
118
 
121
- await setupTestSuiteFromYaml(__dirname);
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
- npx vitest
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.0.6",
3
+ "version": "0.1.0",
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 all YAML test files in a directory and its subdirectories
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
- const testYamlFiles = traverseAllFiles(dirname, extensions);
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,55 @@
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
+ forceRerunTriggers: ["**/*.{test,spec}.{yaml,yml}"],
31
+ },
32
+ };
33
+ },
34
+
35
+ transform(code, id) {
36
+ // Only transform YAML test files
37
+ if (!/\.(test|spec)\.(yaml|yml)$/.test(id)) {
38
+ return null;
39
+ }
40
+
41
+ const yamlDir = path.dirname(id);
42
+
43
+ // Generate a JS module that loads and runs this specific YAML file
44
+ const transformedCode = `
45
+ import { setupTestSuiteFromYaml } from 'puty';
46
+ await setupTestSuiteFromYaml('${yamlDir}', '${path.basename(id)}');
47
+ `;
48
+
49
+ return {
50
+ code: transformedCode,
51
+ map: null,
52
+ };
53
+ },
54
+ };
55
+ }