@jsenv/snapshot 1.0.1 → 1.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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/main.js +79 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/snapshot",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Snapshot testing",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -35,9 +35,9 @@
35
35
  "test": "node --conditions=development ./scripts/test.mjs"
36
36
  },
37
37
  "dependencies": {
38
- "@jsenv/filesystem": "4.5.0",
38
+ "@jsenv/filesystem": "4.5.1",
39
39
  "@jsenv/urls": "2.2.1",
40
- "@jsenv/utils": "2.0.1",
40
+ "@jsenv/utils": "2.1.0",
41
41
  "@jsenv/assert": "2.13.0"
42
42
  }
43
43
  }
package/src/main.js CHANGED
@@ -3,6 +3,11 @@ import {
3
3
  assertAndNormalizeDirectoryUrl,
4
4
  assertAndNormalizeFileUrl,
5
5
  comparePathnames,
6
+ ensureEmptyDirectorySync,
7
+ removeFileSync,
8
+ writeFileSync,
9
+ removeDirectorySync,
10
+ writeFileStructureSync,
6
11
  } from "@jsenv/filesystem";
7
12
  import { urlToFilename, urlToRelativeUrl } from "@jsenv/urls";
8
13
  import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js";
@@ -18,13 +23,54 @@ export const takeDirectorySnapshot = (directoryUrl) => {
18
23
  directoryUrl = assertAndNormalizeDirectoryUrl(directoryUrl);
19
24
  directoryUrl = new URL(directoryUrl);
20
25
 
26
+ const expectedDirectorySnapshot = createDirectorySnapshot(directoryUrl);
27
+ ensureEmptyDirectorySync(directoryUrl);
28
+ return {
29
+ addFile: (relativeUrl, content) => {
30
+ writeFileSync(new URL(relativeUrl, directoryUrl), content);
31
+ },
32
+ compare: () => {
33
+ const actualDirectorySnapshot = createDirectorySnapshot(directoryUrl);
34
+ compareSnapshots(actualDirectorySnapshot, expectedDirectorySnapshot);
35
+ },
36
+ restore: () => {
37
+ if (expectedDirectorySnapshot.notFound) {
38
+ removeDirectorySync(directoryUrl, {
39
+ recursive: true,
40
+ allowUseless: true,
41
+ });
42
+ return;
43
+ }
44
+ if (expectedDirectorySnapshot.empty) {
45
+ ensureEmptyDirectorySync(directoryUrl);
46
+ return;
47
+ }
48
+
49
+ const fileStructure = {};
50
+ Object.keys(expectedDirectorySnapshot.fileSnapshots).forEach(
51
+ (relativeUrl) => {
52
+ const fileSnapshot =
53
+ expectedDirectorySnapshot.fileSnapshots[relativeUrl];
54
+ if (!fileSnapshot.empty) {
55
+ fileStructure[relativeUrl] = fileSnapshot.content;
56
+ }
57
+ },
58
+ );
59
+ writeFileStructureSync(
60
+ directoryUrl,
61
+ expectedDirectorySnapshot.fileStructure,
62
+ );
63
+ },
64
+ };
65
+ };
66
+ const createDirectorySnapshot = (directoryUrl) => {
21
67
  const directorySnapshot = {
22
68
  [snapshotSymbol]: true,
23
69
  empty: false,
24
70
  type: "directory",
25
71
  url: directoryUrl.href,
26
72
  notFound: false,
27
- fileStructure: {},
73
+ fileSnapshots: {},
28
74
  };
29
75
 
30
76
  let stat;
@@ -46,7 +92,7 @@ export const takeDirectorySnapshot = (directoryUrl) => {
46
92
  }
47
93
  }
48
94
 
49
- const snapshotNaturalOrder = {};
95
+ const fileSnapshotsNaturalOrder = {};
50
96
  const visitDirectory = (url) => {
51
97
  try {
52
98
  const directoryContent = readdirSync(url);
@@ -58,7 +104,7 @@ export const takeDirectorySnapshot = (directoryUrl) => {
58
104
  return;
59
105
  }
60
106
  const relativeUrl = urlToRelativeUrl(contentUrl, directoryUrl);
61
- snapshotNaturalOrder[relativeUrl] = takeFileSnapshot(contentUrl);
107
+ fileSnapshotsNaturalOrder[relativeUrl] = createFileSnapshot(contentUrl);
62
108
  });
63
109
  } catch (e) {
64
110
  if (e && e.code === "ENOENT") {
@@ -69,18 +115,37 @@ export const takeDirectorySnapshot = (directoryUrl) => {
69
115
  };
70
116
  visitDirectory(directoryUrl);
71
117
 
72
- const relativeUrls = Object.keys(snapshotNaturalOrder);
118
+ const relativeUrls = Object.keys(fileSnapshotsNaturalOrder);
73
119
  relativeUrls.sort(comparePathnames);
74
120
  relativeUrls.forEach((relativeUrl) => {
75
- directorySnapshot.fileStructure[relativeUrl] =
76
- snapshotNaturalOrder[relativeUrl];
121
+ directorySnapshot.fileSnapshots[relativeUrl] =
122
+ fileSnapshotsNaturalOrder[relativeUrl];
77
123
  });
78
124
  return directorySnapshot;
79
125
  };
80
126
 
81
127
  export const takeFileSnapshot = (fileUrl) => {
82
128
  fileUrl = assertAndNormalizeFileUrl(fileUrl);
83
-
129
+ const expectedFileSnapshot = createFileSnapshot(fileUrl);
130
+ removeFileSync(fileUrl);
131
+ return {
132
+ writeContent: (content) => {
133
+ writeFileSync(fileUrl, content);
134
+ },
135
+ compare: () => {
136
+ const actualFileSnapshot = createFileSnapshot(fileUrl);
137
+ compareSnapshots(actualFileSnapshot, expectedFileSnapshot);
138
+ },
139
+ restore: () => {
140
+ if (expectedFileSnapshot.empty) {
141
+ removeFileSync(fileUrl, { allowUseless: true });
142
+ return;
143
+ }
144
+ writeFileSync(fileUrl, expectedFileSnapshot.content);
145
+ },
146
+ };
147
+ };
148
+ const createFileSnapshot = (fileUrl) => {
84
149
  const fileSnapshot = {
85
150
  [snapshotSymbol]: true,
86
151
  empty: false,
@@ -124,7 +189,7 @@ export const takeFileSnapshot = (fileUrl) => {
124
189
  return fileSnapshot;
125
190
  };
126
191
 
127
- export const compareSnapshots = (currentSnapshot, previousSnapshot) => {
192
+ const compareSnapshots = (currentSnapshot, previousSnapshot) => {
128
193
  if (!currentSnapshot || !currentSnapshot[snapshotSymbol]) {
129
194
  throw new TypeError(
130
195
  `1st argument must be a snapshot, received ${currentSnapshot}`,
@@ -163,10 +228,10 @@ export const compareSnapshots = (currentSnapshot, previousSnapshot) => {
163
228
  const snapshotComparers = {
164
229
  directory: (currentDirectorySnapshot, previousDirectorySnapshot) => {
165
230
  const failureMessage = `comparison with previous directory snapshot failed`;
166
- const currentFileStructure = currentDirectorySnapshot.fileStructure;
167
- const previousFileStructure = previousDirectorySnapshot.fileStructure;
168
- const currentRelativeUrls = Object.keys(currentFileStructure);
169
- const previousRelativeUrls = Object.keys(previousFileStructure);
231
+ const currentFileSnapshots = currentDirectorySnapshot.fileSnapshots;
232
+ const previousFileSnapshots = previousDirectorySnapshot.fileSnapshots;
233
+ const currentRelativeUrls = Object.keys(currentFileSnapshots);
234
+ const previousRelativeUrls = Object.keys(previousFileSnapshots);
170
235
 
171
236
  // missing_files
172
237
  {
@@ -225,8 +290,8 @@ ${extraUrls.join("\n")}`);
225
290
  // file contents
226
291
  {
227
292
  for (const relativeUrl of currentRelativeUrls) {
228
- const currentFileSnapshot = currentFileStructure[relativeUrl];
229
- const previousFileSnapshot = previousFileStructure[relativeUrl];
293
+ const currentFileSnapshot = currentFileSnapshots[relativeUrl];
294
+ const previousFileSnapshot = previousFileSnapshots[relativeUrl];
230
295
  compareSnapshots(currentFileSnapshot, previousFileSnapshot);
231
296
  }
232
297
  }