Skip to content

Commit dea364e

Browse files
authored
[fs][FIX] adapters/Memory: Return cloned resources (SAP/ui5-fs#235)
Also makes sure to pass the project reference when cloning a resource
1 parent df75d3d commit dea364e

3 files changed

Lines changed: 94 additions & 32 deletions

File tree

packages/fs/lib/Resource.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,8 @@ class Resource {
261261
clone() {
262262
const options = {
263263
path: this._path,
264-
statInfo: clone(this._statInfo)
264+
statInfo: clone(this._statInfo),
265+
project: this._project
265266
};
266267

267268
const addContentOption = () => {

packages/fs/lib/adapters/Memory.js

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@ class Memory extends AbstractAdapter {
2525
this._virDirs = {}; // map full of directories
2626
}
2727

28+
/**
29+
* Matches and returns resources from a given map (either _virFiles or _virDirs).
30+
*
31+
* @private
32+
* @param {string[]} patterns
33+
* @param {object} resourceMap
34+
* @returns {Promise<module:@ui5/fs.Resource[]>}
35+
*/
36+
async _matchPatterns(patterns, resourceMap) {
37+
const resourcePaths = Object.keys(resourceMap);
38+
const matchedPaths = micromatch(resourcePaths, patterns, {
39+
dot: true
40+
});
41+
return Promise.all(matchedPaths.map((virPath) => {
42+
return resourceMap[virPath] && resourceMap[virPath].clone();
43+
}));
44+
}
45+
2846
/**
2947
* Locate resources by glob.
3048
*
@@ -50,22 +68,11 @@ class Memory extends AbstractAdapter {
5068
];
5169
}
5270

53-
const filePaths = Object.keys(this._virFiles);
54-
const matchedFilePaths = micromatch(filePaths, patterns, {
55-
dot: true
56-
});
57-
let matchedResources = matchedFilePaths.map((virPath) => {
58-
return this._virFiles[virPath];
59-
});
71+
let matchedResources = await this._matchPatterns(patterns, this._virFiles);
6072

6173
if (!options.nodir) {
62-
const dirPaths = Object.keys(this._virDirs);
63-
const matchedDirs = micromatch(dirPaths, patterns, {
64-
dot: true
65-
});
66-
matchedResources = matchedResources.concat(matchedDirs.map((virPath) => {
67-
return this._virDirs[virPath];
68-
}));
74+
const matchedDirs = await this._matchPatterns(patterns, this._virDirs);
75+
matchedResources = matchedResources.concat(matchedDirs);
6976
}
7077

7178
return matchedResources;
@@ -80,28 +87,25 @@ class Memory extends AbstractAdapter {
8087
* @param {module:@ui5/fs.tracing.Trace} trace Trace instance
8188
* @returns {Promise<module:@ui5/fs.Resource>} Promise resolving to a single resource
8289
*/
83-
_byPath(virPath, options, trace) {
90+
async _byPath(virPath, options, trace) {
8491
if (this.isPathExcluded(virPath)) {
85-
return Promise.resolve(null);
92+
return null;
93+
}
94+
if (!virPath.startsWith(this._virBasePath) && virPath !== this._virBaseDir) {
95+
// Neither starts with basePath, nor equals baseDirectory
96+
return null;
8697
}
87-
return new Promise((resolve, reject) => {
88-
if (!virPath.startsWith(this._virBasePath) && virPath !== this._virBaseDir) {
89-
// Neither starts with basePath, nor equals baseDirectory
90-
resolve(null);
91-
return;
92-
}
9398

94-
const relPath = virPath.substr(this._virBasePath.length);
95-
trace.pathCall();
99+
const relPath = virPath.substr(this._virBasePath.length);
100+
trace.pathCall();
96101

97-
const resource = this._virFiles[relPath];
102+
const resource = this._virFiles[relPath];
98103

99-
if (!resource || (options.nodir && resource.getStatInfo().isDirectory())) {
100-
resolve(null);
101-
} else {
102-
resolve(resource);
103-
}
104-
});
104+
if (!resource || (options.nodir && resource.getStatInfo().isDirectory())) {
105+
return null;
106+
} else {
107+
return await resource.clone();
108+
}
105109
}
106110

107111
/**

packages/fs/test/lib/adapters/Memory_read.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const test = require("ava");
22
const {resourceFactory} = require("../../../");
3+
const MemoryAdapter = require("../../../lib/adapters/Memory");
34

45
async function fillFromFs(readerWriter, {fsBasePath = "./test/fixtures/glob", virBasePath = "/app/"} = {}) {
56
const fsReader = resourceFactory.createAdapter({
@@ -606,3 +607,59 @@ test("static excludes: glob with negated directory exclude, not excluding resour
606607

607608
t.deepEqual(resources.length, 4, "Found two resources and two directories");
608609
});
610+
611+
test("byPath returns new resource", async (t) => {
612+
const originalResource = resourceFactory.createResource({
613+
path: "/app/index.html",
614+
string: "test"
615+
});
616+
617+
const memoryAdapter = new MemoryAdapter({virBasePath: "/"});
618+
619+
await memoryAdapter.write(originalResource);
620+
621+
const returnedResource = await memoryAdapter.byPath("/app/index.html");
622+
623+
t.deepEqual(returnedResource, originalResource,
624+
"Returned resource should be deep equal to original resource");
625+
t.not(returnedResource, originalResource,
626+
"Returned resource should not have same reference as original resource");
627+
628+
const anotherReturnedResource = await memoryAdapter.byPath("/app/index.html");
629+
630+
t.deepEqual(anotherReturnedResource, originalResource,
631+
"Returned resource should be deep equal to original resource");
632+
t.not(anotherReturnedResource, originalResource,
633+
"Returned resource should not have same reference as original resource");
634+
635+
t.not(returnedResource, anotherReturnedResource,
636+
"Both returned resources should not have same reference");
637+
});
638+
639+
test("byGlob returns new resources", async (t) => {
640+
const originalResource = resourceFactory.createResource({
641+
path: "/app/index.html",
642+
string: "test"
643+
});
644+
645+
const memoryAdapter = new MemoryAdapter({virBasePath: "/"});
646+
647+
await memoryAdapter.write(originalResource);
648+
649+
const [returnedResource] = await memoryAdapter.byGlob("/**");
650+
651+
t.deepEqual(returnedResource, originalResource,
652+
"Returned resource should be deep equal to the original resource");
653+
t.not(returnedResource, originalResource,
654+
"Returned resource should not have same reference as the original resource");
655+
656+
const [anotherReturnedResource] = await memoryAdapter.byGlob("/**");
657+
658+
t.deepEqual(anotherReturnedResource, originalResource,
659+
"Another returned resource should be deep equal to the original resource");
660+
t.not(anotherReturnedResource, originalResource,
661+
"Another returned resource should not have same reference as the original resource");
662+
663+
t.not(returnedResource, anotherReturnedResource,
664+
"Both returned resources should not have same reference");
665+
});

0 commit comments

Comments
 (0)