fs-fixture 1.1.0 → 2.0.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 +66 -38
- package/dist/index.cjs +1 -0
- package/dist/{index.d.ts → index.d.cts} +13 -4
- package/dist/index.d.mts +46 -0
- package/dist/index.mjs +1 -1
- package/package.json +14 -6
- package/dist/index.js +0 -1
package/README.md
CHANGED
|
@@ -1,45 +1,54 @@
|
|
|
1
|
-
# fs-fixture
|
|
1
|
+
# fs-fixture [](https://npm.im/fs-fixture) [](https://npm.im/fs-fixture)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Simple API to create disposable test fixtures on disk.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Usage
|
|
8
|
-
|
|
9
|
-
### JSON input
|
|
10
|
-
|
|
11
|
-
Pass in an object representing the test fixture.
|
|
5
|
+
Tiny (`560 B` gzipped) and no dependencies!
|
|
12
6
|
|
|
7
|
+
### Example
|
|
13
8
|
```ts
|
|
9
|
+
import fs from 'fs/promises'
|
|
14
10
|
import { createFixture } from 'fs-fixture'
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
directoryB: {
|
|
22
|
-
fileNameA: 'fileContent'
|
|
23
|
-
}
|
|
24
|
-
},
|
|
12
|
+
const fixture = await createFixture({
|
|
13
|
+
'dir-a': {
|
|
14
|
+
'file-b': 'hello world'
|
|
15
|
+
}
|
|
16
|
+
})
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
const content = await fs.readFile(fixture.getPath('dir-a/file-b'))
|
|
19
|
+
console.log(content)
|
|
20
|
+
```
|
|
29
21
|
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://github.com/sponsors/privatenumber/sponsorships?tier_id=398771"><img width="412" src="https://raw.githubusercontent.com/privatenumber/sponsors/master/banners/assets/donate.webp"></a>
|
|
24
|
+
<a href="https://github.com/sponsors/privatenumber/sponsorships?tier_id=397608"><img width="412" src="https://raw.githubusercontent.com/privatenumber/sponsors/master/banners/assets/sponsor.webp"></a>
|
|
25
|
+
</p>
|
|
26
|
+
<p align="center"><sup><i>Already a sponsor?</i> Join the discussion in the <a href="https://github.com/pvtnbr/fs-fixture">Development repo</a>!</sup></p>
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
console.log(fixture.path)
|
|
28
|
+
## Usage
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
Pass in an object representing the file structure:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { createFixture } from 'fs-fixture'
|
|
34
|
+
|
|
35
|
+
const fixture = await createFixture({
|
|
36
|
+
// Nested directory syntax
|
|
37
|
+
'dir-a': {
|
|
38
|
+
'dir-b': {
|
|
39
|
+
'file-a.txt': 'hello world'
|
|
40
|
+
}
|
|
41
|
+
},
|
|
39
42
|
|
|
40
|
-
//
|
|
41
|
-
|
|
43
|
+
// Alternatively, use the directory path syntax - Same as above
|
|
44
|
+
'dir-a/dir-b/file-b.txt': 'goodbye world'
|
|
42
45
|
})
|
|
46
|
+
|
|
47
|
+
// Interact with the fixture
|
|
48
|
+
console.log(fixture.path)
|
|
49
|
+
|
|
50
|
+
// Cleanup fixture
|
|
51
|
+
await fixture.rm()
|
|
43
52
|
```
|
|
44
53
|
|
|
45
54
|
### Template path input
|
|
@@ -47,15 +56,23 @@ test('my test using json fixture', async () => {
|
|
|
47
56
|
Pass in a path to a test fixture template directory to make a copy of it.
|
|
48
57
|
|
|
49
58
|
```ts
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const fixture = await createFixture('./fixtures/template-a')
|
|
59
|
+
// Pass in a path to a fixture template path, and it will make a copy of it
|
|
60
|
+
const fixture = await createFixture('./fixtures/template-a')
|
|
53
61
|
|
|
54
|
-
|
|
62
|
+
/* Your test code here... */
|
|
55
63
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
// Cleanup fixture
|
|
65
|
+
await fixture.rm()
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `using` keyword (Explicit Resource Management)
|
|
69
|
+
|
|
70
|
+
[TypeScript 5.2](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html) supports the [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) feature, which allows you to instantiate the fixture via `using`. When the fixture is declared this way, it gets automatically cleaned up when exiting the scope.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
await using fixture = await createFixture({ file: 'hello' })
|
|
74
|
+
|
|
75
|
+
// No need to run fixture.rm()
|
|
59
76
|
```
|
|
60
77
|
|
|
61
78
|
## API
|
|
@@ -93,6 +110,11 @@ class FsFixture {
|
|
|
93
110
|
*/
|
|
94
111
|
constructor(fixturePath: string)
|
|
95
112
|
|
|
113
|
+
/**
|
|
114
|
+
Get the full path to a subpath in the fixture directory.
|
|
115
|
+
*/
|
|
116
|
+
getPath(subpath: string): string
|
|
117
|
+
|
|
96
118
|
/**
|
|
97
119
|
Check if the fixture exists. Pass in a subpath to check if it exists.
|
|
98
120
|
*/
|
|
@@ -111,7 +133,7 @@ class FsFixture {
|
|
|
111
133
|
/**
|
|
112
134
|
Create a JSON file in the fixture directory.
|
|
113
135
|
*/
|
|
114
|
-
writeJson(filePath: string, json:
|
|
136
|
+
writeJson(filePath: string, json: unknown): Promise<void>
|
|
115
137
|
|
|
116
138
|
/**
|
|
117
139
|
Read a file from the fixture directory.
|
|
@@ -119,3 +141,9 @@ class FsFixture {
|
|
|
119
141
|
readFile(filePath: string, encoding?: BufferEncoding): Promise<string | Buffer>
|
|
120
142
|
}
|
|
121
143
|
```
|
|
144
|
+
|
|
145
|
+
## Related
|
|
146
|
+
|
|
147
|
+
### [manten](https://github.com/privatenumber/manten)
|
|
148
|
+
|
|
149
|
+
Lightweight testing library for Node.js
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=require("fs/promises"),s=require("path"),u=require("fs"),l=require("os");typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{configurable:!1,enumerable:!1,writable:!1,value:Symbol.for("asyncDispose")});class h{path;constructor(t){this.path=t}getPath(t){return s.join(this.path,t)}exists(t=""){return i.access(this.getPath(t)).then(()=>!0,()=>!1)}rm(t=""){return i.rm(this.getPath(t),{recursive:!0,force:!0})}writeFile(t,e){return i.writeFile(this.getPath(t),e)}writeJson(t,e){return this.writeFile(t,JSON.stringify(e,null,2))}readFile(t,e){return i.readFile(this.getPath(t),e)}async[Symbol.asyncDispose](){await this.rm()}}const f=u.realpathSync(l.tmpdir()),p=`fs-fixture-${Date.now()}`;let o=0;const y=()=>(o+=1,o),c=(r,t)=>{const e=[];for(const a in r){if(!Object.hasOwn(r,a))continue;const n=r[a];typeof n=="string"?e.push({path:s.join(t,a),content:n}):e.push(...c(n,s.join(t,a)))}return e},m=async r=>{const t=s.join(f,`${p}-${y()}`);return await i.mkdir(t,{recursive:!0}),r&&(typeof r=="string"?await i.cp(r,t,{recursive:!0}):typeof r=="object"&&await Promise.all(c(r,t).map(async e=>{await i.mkdir(s.dirname(e.path),{recursive:!0}),await i.writeFile(e.path,e.content)}))),new h(t)};exports.createFixture=m;
|
|
@@ -8,6 +8,10 @@ declare class FsFixture {
|
|
|
8
8
|
*/
|
|
9
9
|
constructor(fixturePath: string);
|
|
10
10
|
/**
|
|
11
|
+
Get the full path to a subpath in the fixture directory.
|
|
12
|
+
*/
|
|
13
|
+
getPath(subpath: string): string;
|
|
14
|
+
/**
|
|
11
15
|
Check if the fixture exists. Pass in a subpath to check if it exists.
|
|
12
16
|
*/
|
|
13
17
|
exists(subpath?: string): Promise<boolean>;
|
|
@@ -22,16 +26,21 @@ declare class FsFixture {
|
|
|
22
26
|
/**
|
|
23
27
|
Create a JSON file in the fixture directory.
|
|
24
28
|
*/
|
|
25
|
-
writeJson(filePath: string, json:
|
|
29
|
+
writeJson(filePath: string, json: unknown): Promise<void>;
|
|
26
30
|
/**
|
|
27
31
|
Read a file from the fixture directory.
|
|
28
32
|
*/
|
|
29
33
|
readFile(filePath: string, encoding?: BufferEncoding): Promise<string | Buffer>;
|
|
34
|
+
/**
|
|
35
|
+
* Resource management cleanup
|
|
36
|
+
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html
|
|
37
|
+
*/
|
|
38
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
type FileTree = {
|
|
33
42
|
[path: string]: string | FileTree;
|
|
34
43
|
};
|
|
35
|
-
declare
|
|
44
|
+
declare const createFixture: (source?: string | FileTree) => Promise<FsFixture>;
|
|
36
45
|
|
|
37
|
-
export { FileTree, FsFixture, createFixture };
|
|
46
|
+
export { type FileTree, FsFixture, createFixture };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
declare class FsFixture {
|
|
2
|
+
/**
|
|
3
|
+
Path to the fixture directory.
|
|
4
|
+
*/
|
|
5
|
+
path: string;
|
|
6
|
+
/**
|
|
7
|
+
Create a Fixture instance from a path. Does not create the fixture directory.
|
|
8
|
+
*/
|
|
9
|
+
constructor(fixturePath: string);
|
|
10
|
+
/**
|
|
11
|
+
Get the full path to a subpath in the fixture directory.
|
|
12
|
+
*/
|
|
13
|
+
getPath(subpath: string): string;
|
|
14
|
+
/**
|
|
15
|
+
Check if the fixture exists. Pass in a subpath to check if it exists.
|
|
16
|
+
*/
|
|
17
|
+
exists(subpath?: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
Delete the fixture directory. Pass in a subpath to delete it.
|
|
20
|
+
*/
|
|
21
|
+
rm(subpath?: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
Create a file in the fixture directory.
|
|
24
|
+
*/
|
|
25
|
+
writeFile(filePath: string, content: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
Create a JSON file in the fixture directory.
|
|
28
|
+
*/
|
|
29
|
+
writeJson(filePath: string, json: unknown): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
Read a file from the fixture directory.
|
|
32
|
+
*/
|
|
33
|
+
readFile(filePath: string, encoding?: BufferEncoding): Promise<string | Buffer>;
|
|
34
|
+
/**
|
|
35
|
+
* Resource management cleanup
|
|
36
|
+
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html
|
|
37
|
+
*/
|
|
38
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
type FileTree = {
|
|
42
|
+
[path: string]: string | FileTree;
|
|
43
|
+
};
|
|
44
|
+
declare const createFixture: (source?: string | FileTree) => Promise<FsFixture>;
|
|
45
|
+
|
|
46
|
+
export { type FileTree, FsFixture, createFixture };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import i from"fs/promises";import s from"path";import l from"fs";import f from"os";typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{configurable:!1,enumerable:!1,writable:!1,value:Symbol.for("asyncDispose")});class p{path;constructor(t){this.path=t}getPath(t){return s.join(this.path,t)}exists(t=""){return i.access(this.getPath(t)).then(()=>!0,()=>!1)}rm(t=""){return i.rm(this.getPath(t),{recursive:!0,force:!0})}writeFile(t,e){return i.writeFile(this.getPath(t),e)}writeJson(t,e){return this.writeFile(t,JSON.stringify(e,null,2))}readFile(t,e){return i.readFile(this.getPath(t),e)}async[Symbol.asyncDispose](){await this.rm()}}const u=l.realpathSync(f.tmpdir()),h=`fs-fixture-${Date.now()}`;let o=0;const m=()=>(o+=1,o),c=(r,t)=>{const e=[];for(const a in r){if(!Object.hasOwn(r,a))continue;const n=r[a];typeof n=="string"?e.push({path:s.join(t,a),content:n}):e.push(...c(n,s.join(t,a)))}return e},y=async r=>{const t=s.join(u,`${h}-${m()}`);return await i.mkdir(t,{recursive:!0}),r&&(typeof r=="string"?await i.cp(r,t,{recursive:!0}):typeof r=="object"&&await Promise.all(c(r,t).map(async e=>{await i.mkdir(s.dirname(e.path),{recursive:!0}),await i.writeFile(e.path,e.content)}))),new p(t)};export{y as createFixture};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fs-fixture",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Easily create test fixtures at a temporary file-system path",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"test",
|
|
@@ -22,13 +22,18 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"dist"
|
|
24
24
|
],
|
|
25
|
-
"main": "./dist/index.
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
26
|
"module": "./dist/index.mjs",
|
|
27
|
-
"types": "./dist/index.d.
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
28
|
"exports": {
|
|
29
|
-
"require":
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/index.d.cts",
|
|
31
|
+
"default": "./dist/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/index.d.mts",
|
|
35
|
+
"default": "./dist/index.mjs"
|
|
36
|
+
}
|
|
32
37
|
},
|
|
33
38
|
"imports": {
|
|
34
39
|
"#fs-fixture": {
|
|
@@ -36,5 +41,8 @@
|
|
|
36
41
|
"development": "./src/index.ts",
|
|
37
42
|
"default": "./dist/index.mjs"
|
|
38
43
|
}
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
39
47
|
}
|
|
40
48
|
}
|
package/dist/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var i=require("fs"),l=require("path"),p=require("os");function u(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var c=u(i),a=u(l),d=u(p);class h{path;constructor(t){this.path=t}exists(t=""){return i.promises.access(a.default.join(this.path,t)).then(()=>!0,()=>!1)}rm(t=""){return i.promises.rm(a.default.join(this.path,t),{recursive:!0,force:!0})}writeFile(t,r){return i.promises.writeFile(a.default.join(this.path,t),r)}writeJson(t,r){return this.writeFile(t,JSON.stringify(r,null,2))}readFile(t,r){return i.promises.readFile(a.default.join(this.path,t),r)}}const m=a.default.join(c.default.realpathSync(d.default.tmpdir()),"test-fixtures",Date.now().toString());let o=0;function w(){return o+=1,o}const{hasOwnProperty:y}=Object.prototype,j=(e,t)=>y.call(e,t);function f(e,t){const r=[];for(const s in e){if(!j(e,s))continue;const n=e[s];typeof n=="string"?r.push({path:a.default.join(t,s),content:n}):r.push(...f(n,a.default.join(t,s)))}return r}async function v(e){const t=a.default.join(m,`fixture-${w()}`);return await i.promises.mkdir(t,{recursive:!0}),e&&(typeof e=="string"?await i.promises.cp(e,t,{recursive:!0}):typeof e=="object"&&await Promise.all(f(e,t).map(async r=>{await i.promises.mkdir(a.default.dirname(r.path),{recursive:!0}),await i.promises.writeFile(r.path,r.content)}))),new h(t)}exports.createFixture=v;
|