diff --git a/lib/adapters/AbstractAdapter.js b/lib/adapters/AbstractAdapter.js index 8a450109..db08473b 100644 --- a/lib/adapters/AbstractAdapter.js +++ b/lib/adapters/AbstractAdapter.js @@ -1,6 +1,7 @@ const log = require("@ui5/logger").getLogger("resources:adapters:AbstractAdapter"); const minimatch = require("minimatch"); const AbstractReaderWriter = require("../AbstractReaderWriter"); +const Resource = require("../Resource"); /** * Abstract Resource Adapter @@ -49,6 +50,25 @@ class AbstractAdapter extends AbstractReaderWriter { return []; } patterns = Array.prototype.concat.apply([], patterns); + if (!options.nodir) { + for (let i = patterns.length - 1; i >= 0; i--) { + const idx = this._virBaseDir.indexOf(patterns[i]); + if (patterns[i] && idx !== -1 && idx < this._virBaseDir.length) { + const subPath = patterns[i]; + return Promise.resolve([ + new Resource({ + project: this.project, + statInfo: { // TODO: make closer to fs stat info + isDirectory: function() { + return true; + } + }, + path: subPath + }) + ]); + } + } + } return this._runGlob(patterns, options, trace); }); } @@ -62,6 +82,7 @@ class AbstractAdapter extends AbstractReaderWriter { */ _normalizePattern(virPattern) { return Promise.resolve().then(() => { + const that = this; const mm = new minimatch.Minimatch(virPattern); const basePathParts = this._virBaseDir.split("/"); @@ -71,41 +92,50 @@ class AbstractAdapter extends AbstractReaderWriter { for (i = 0; i < basePathParts.length; i++) { const globPart = subset[i]; if (globPart === undefined) { - log.verbose("Ran out of glob parts to match. This should not happen."); - return -42; + log.verbose("Ran out of glob parts to match (this should not happen):"); + if (that._project) { // project is optional + log.verbose(`Project: ${that._project.metadata.name}`); + } + log.verbose(`Virtual base path: ${that._virBaseDir}`); + log.verbose(`Pattern to match: ${virPattern}`); + log.verbose(`Current subset (tried index ${i}):`); + log.verbose(subset); + return {idx: i, virtualMatch: true}; } const basePathPart = basePathParts[i]; if (typeof globPart === "string") { if (globPart !== basePathPart) { - return -42; + return null; } else { continue; } } else if (globPart === minimatch.GLOBSTAR) { - return i; + return {idx: i}; } else { // Regex if (!globPart.test(basePathPart)) { - return -42; + return null; } else { continue; } } } if (subset.length === basePathParts.length) { - return -1; + return {rootMatch: true}; } - return i; + return {idx: i}; } const resultGlobs = []; for (let i = 0; i < mm.set.length; i++) { - const matchIdx = matchSubset(mm.set[i]); - let resultPattern; - if (matchIdx !== -42) { - if (matchIdx === -1) { // matched one up + const match = matchSubset(mm.set[i]); + if (match) { + let resultPattern; + if (match.virtualMatch) { + resultPattern = basePathParts.slice(0, match.idx).join("/"); + } else if (match.rootMatch) { // matched one up resultPattern = ""; // root "/" } else { // matched at some part of the glob - resultPattern = mm.globParts[i].slice(matchIdx).join("/"); + resultPattern = mm.globParts[i].slice(match.idx).join("/"); if (resultPattern.startsWith("/")) { resultPattern = resultPattern.substr(1); } diff --git a/lib/adapters/Memory.js b/lib/adapters/Memory.js index 1e37280f..04cffc41 100644 --- a/lib/adapters/Memory.js +++ b/lib/adapters/Memory.js @@ -50,22 +50,24 @@ class Memory extends AbstractAdapter { } const filePaths = Object.keys(this._virFiles); - let matchedResources = micromatch(filePaths, patterns, { + const matchedFilePaths = micromatch(filePaths, patterns, { dot: true }); + let matchedResources = matchedFilePaths.map((virPath) => { + return this._virFiles[virPath]; + }); if (!options.nodir) { - // TODO: Add tests for all this const dirPaths = Object.keys(this._virDirs); const matchedDirs = micromatch(dirPaths, patterns, { dot: true }); - matchedResources = matchedResources.concat(matchedDirs); + matchedResources = matchedResources.concat(matchedDirs.map((virPath) => { + return this._virDirs[virPath]; + })); } - return Promise.resolve(matchedResources.map((virPath) => { - return this._virFiles[virPath]; - })); + return Promise.resolve(matchedResources); } /** @@ -117,9 +119,8 @@ class Memory extends AbstractAdapter { pathSegments.pop(); // Remove last segment representing the resource itself pathSegments.forEach((segment, i) => { - segment = "/" + segment; - if (i > 1) { - segment = pathSegments[i - 1] + segment; + if (i >= 1) { + segment = pathSegments[i - 1] + "/" + segment; } pathSegments[i] = segment; }); @@ -134,7 +135,7 @@ class Memory extends AbstractAdapter { return true; } }, - path: segment + path: this._virBasePath + segment }); } } diff --git a/test/lib/adapters/FileSystem.js b/test/lib/adapters/FileSystem.js new file mode 100644 index 00000000..779573ea --- /dev/null +++ b/test/lib/adapters/FileSystem.js @@ -0,0 +1,63 @@ +const {test} = require("ava"); +const {resourceFactory} = require("../../../"); + +test("GLOB resources from application.a w/ virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/" + }); + + const resources = await readerWriter.byGlob("/app/**/*.html"); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB resources from application.a w/o virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/" + }); + + const resources = await readerWriter.byGlob("/**/*.html"); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + + +test("GLOB virtual directory w/o virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/" + }); + + const resources = await readerWriter.byGlob("/*", {nodir: false}); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB virtual directory w/ virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/one/two/" + }); + + const resources = await readerWriter.byGlob("/app/*", {nodir: false}); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB virtual directory w/o virtual base path prefix and nodir: true", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/" + }); + + const resources = await readerWriter.byGlob("/*", {nodir: true}); + t.deepEqual(resources.length, 0, "Found no resources"); +}); + +test("GLOB virtual directory w/ virtual base path prefix and nodir: true", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/one/two/" + }); + + const resources = await readerWriter.byGlob("/app/*", {nodir: true}); + t.deepEqual(resources.length, 0, "Found no resources"); +}); diff --git a/test/lib/adapters/Memory.js b/test/lib/adapters/Memory.js new file mode 100644 index 00000000..f2a5f3df --- /dev/null +++ b/test/lib/adapters/Memory.js @@ -0,0 +1,321 @@ +const {test} = require("ava"); +const {resourceFactory} = require("../../../"); + +async function fillFromFs(readerWriter) { + const fsReader = resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/glob", + virBasePath: "/app/", + }); + + const fsResources = await fsReader.byGlob("/**/*"); + return Promise.all(fsResources.map(function(resource) { + return readerWriter.write(resource); + })); +} + +function matchGlobResult(t, resources, expectedResources) { + t.deepEqual(resources.length, expectedResources.length, "Amount of files matches expected result."); + + const matchedResources = resources.map((resource) => { + return resource.getPath(); + }); + + for (let i = 0; i < expectedResources.length; i++) { + const expectedResource = expectedResources[i]; + t.true( + matchedResources.indexOf(expectedResource) !== -1, + "File '" + expectedResource + "' was found." + ); + } +} + +test("GLOB resources from application.a w/ virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + + const resource = resourceFactory.createResource({ + path: "/app/index.html", + string: "test" + }); + await readerWriter.write(resource); + + const resources = await readerWriter.byGlob("/app/*.html"); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB resources from application.a w/o virtual base path prefix", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + + const resource = resourceFactory.createResource({ + path: "/app/index.html", + string: "test" + }); + await readerWriter.write(resource); + + const resources = await readerWriter.byGlob("/**/*.html"); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB virtual directory w/o virtual base path prefix", async (t) => { + // TODO: Add similar test (globbing on empty directory) for FS RL + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/one/two" + }); + + const resources = await readerWriter.byGlob("/*", {nodir: false}); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB virtual directory w/ virtual base path prefix", async (t) => { + // TODO: Add similar test (globbing on empty directory) for FS RL + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/one/two/" + }); + + const resources = await readerWriter.byGlob("/app/*", {nodir: false}); + t.deepEqual(resources.length, 1, "Found exactly one resource"); +}); + +test("GLOB virtual directory w/o virtual base path prefix and nodir: true", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/one/two" + }); + + const resources = await readerWriter.byGlob("/*", {nodir: true}); + t.deepEqual(resources.length, 0, "Found no resources"); +}); + +test("GLOB virtual directory w/ virtual base path prefix and nodir: true", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/one/two/" + }); + + const resources = await readerWriter.byGlob("/app/*", {nodir: true}); + t.deepEqual(resources.length, 0, "Found no resources"); +}); + +/* Load more data from FS into memory */ +test("GLOB all", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + const resources = await readerWriter.byGlob("/**/*.*"); + t.deepEqual(resources.length, 16, "Found all resources"); +}); + +test("GLOB all from root", async (t) => { + t.plan(2); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + const resources = await readerWriter.byGlob("/*/*.*"); + matchGlobResult(t, resources, ["/app/package.json"]); +}); + +test("GLOB all with virtual path included", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob("/app/**/*.*"); + t.deepEqual(resources.length, 16, "Found all resources"); +}); + +test("GLOB a specific filetype (yaml)", async (t) => { + t.plan(2); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob("/**/*.yaml"); + resources.forEach((res) => { + t.deepEqual(res._name, "ui5.yaml"); + }); +}); + +test("GLOB two specific filetype (yaml and js)", async (t) => { + t.plan(4); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob("/**/*.{yaml,js}"); + const expectedFiles = [ + "/app/application.b/ui5.yaml", + "/app/application.a/ui5.yaml", + "/app/application.a/webapp/test.js" + ]; + matchGlobResult(t, resources, expectedFiles); +}); + +test("GLOB a specific filetype (json) with exclude pattern", async (t) => { + t.plan(3); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob([ + "/**/*.json", + "!/**/*package.json" + ]); + const expectedFiles = [ + "/app/application.b/webapp/manifest.json", + "/app/application.b/webapp/embedded/manifest.json" + ]; + matchGlobResult(t, resources, expectedFiles); +}); + +test("GLOB a specific filetype (json) with multiple exclude pattern", async (t) => { + t.plan(2); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob([ + "/**/*.json", + "!/**/*package.json", + "!/**/embedded/manifest.json" + ]); + matchGlobResult(t, resources, ["/app/application.b/webapp/manifest.json"]); +}); + +test("GLOB (normalized) root directory (=> fs root)", async (t) => { + t.plan(2); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob([ + "/*/", + ], {nodir: false}); + resources.forEach((res) => { + t.deepEqual(res._name, "app"); + t.deepEqual(res.getStatInfo().isDirectory(), true); + }); +}); + +test("GLOB root directory", async (t) => { + t.plan(2); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob("/app/", {nodir: false}); + matchGlobResult(t, resources, ["/app"]); +}); + +test("GLOB subdirectory", async (t) => { + t.plan(3); + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + await fillFromFs(readerWriter); + + const resources = await readerWriter.byGlob([ + "/app/application.a", + ], {nodir: false}); + + t.deepEqual(resources.length, 1, "Found one resource"); + t.deepEqual(resources[0].getPath(), "/app/application.a"); + t.deepEqual(resources[0].getStatInfo().isDirectory(), true); +}); + +test("Write resource w/ virtual base path", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/" + }); + + const res = resourceFactory.createResource({ + path: "/app/test.html" + }); + await readerWriter.write(res); + + t.deepEqual(readerWriter._virFiles, { + "test.html": res + }, "Adapter added resource with correct path"); + + t.deepEqual(Object.keys(readerWriter._virDirs), [], "Adapter added correct virtual directories"); +}); + +test("Write resource w/o virtual base path", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/" + }); + + const res = resourceFactory.createResource({ + path: "/one/two/three/test.html" + }); + await readerWriter.write(res); + + t.deepEqual(readerWriter._virFiles, { + "one/two/three/test.html": res + }, "Adapter added resource with correct path"); + + t.deepEqual(Object.keys(readerWriter._virDirs), [ + "one/two/three", + "one/two", + "one" + ], "Adapter added correct virtual directories"); + + const dirRes = readerWriter._virDirs["one/two/three"]; + t.deepEqual(dirRes.getStatInfo().isDirectory(), true, "Directory resource is a directory"); + t.deepEqual(dirRes.getPath(), "/one/two/three", "Directory resource has correct path"); +}); + +test("Write resource w/ deep virtual base path", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/a/" + }); + + const res = resourceFactory.createResource({ + path: "/app/a/one/two/three/test.html" + }); + await readerWriter.write(res); + + t.deepEqual(readerWriter._virFiles, { + "one/two/three/test.html": res + }, "Adapter added resource with correct path"); + + t.deepEqual(Object.keys(readerWriter._virDirs), [ + "one/two/three", + "one/two", + "one" + ], "Adapter added correct virtual directories"); + + const dirRes = readerWriter._virDirs["one/two/three"]; + t.deepEqual(dirRes.getStatInfo().isDirectory(), true, "Directory resource is a directory"); + t.deepEqual(dirRes.getPath(), "/app/a/one/two/three", "Directory resource has correct path"); +}); + +test("Write resource w/ crazy virtual base path", async (t) => { + const readerWriter = resourceFactory.createAdapter({ + virBasePath: "/app/🐛/" + }); + + const res = resourceFactory.createResource({ + path: "/app/🐛/one\\/2/3️⃣/test" + }); + await readerWriter.write(res); + + t.deepEqual(readerWriter._virFiles, { + "one\\/2/3️⃣/test": res + }, "Adapter added resource with correct path"); + + t.deepEqual(Object.keys(readerWriter._virDirs), [ + "one\\/2/3️⃣", + "one\\/2", + "one\\" + ], "Adapter added correct virtual directories"); +}); diff --git a/test/lib/glob.js b/test/lib/glob.js index 32f8541a..a552a0d4 100644 --- a/test/lib/glob.js +++ b/test/lib/glob.js @@ -1,7 +1,6 @@ const {test} = require("ava"); const ui5Fs = require("../../"); const FsAdapter = ui5Fs.adapters.FileSystem; -const MemAdapter = ui5Fs.adapters.Memory; // Create readerWriter before running tests test.beforeEach((t) => { @@ -9,19 +8,7 @@ test.beforeEach((t) => { filesystem: new FsAdapter({ fsBasePath: "./test/fixtures/glob", virBasePath: "/test-resources/" - }), - memory: new MemAdapter({ - virBasePath: "/test-resources/" - }), - fromMemory: function(pattern, options) { - return t.context.readerWriter.filesystem.byGlob(pattern, options).then((resources) => { - return Promise.all(resources.map(function(resource) { - return t.context.readerWriter.memory.write(resource); - })).then(() => { - return t.context.readerWriter.memory.byGlob(pattern, options); - }); - }); - } + }) }; }); @@ -202,107 +189,3 @@ test("GLOB subdirectory", (t) => { }); }); }); - - -// From Memory -test("GLOB all from memory", (t) => { - return t.context.readerWriter.fromMemory("/**/*.*") - .then((resources) => { - t.deepEqual(resources.length, 16, "Found all resources"); - }); -}); - -test("GLOB all from root only from memory", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory("/*/*.*") - .then((resources) => { - matchGlobResult(t, resources, ["/test-resources/package.json"]); - }); -}); - -test("GLOB all with virtual path included from memory", (t) => { - return t.context.readerWriter.fromMemory("/test-resources/**/*.*") - .then((resources) => { - t.deepEqual(resources.length, 16, "Found all resources"); - }); -}); - -test("GLOB only a specific filetype (yaml) from memory", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory("/**/*.yaml") - .then((resources) => { - resources.forEach((res) => { - t.deepEqual(res._name, "ui5.yaml"); - }); - }); -}); - -test("GLOB two specific filetype (yaml and js) from memory", (t) => { - t.plan(4); - return t.context.readerWriter.fromMemory("/**/*.{yaml,js}") - .then((resources) => { - const expectedFiles = [ - "/test-resources/application.b/ui5.yaml", - "/test-resources/application.a/ui5.yaml", - "/test-resources/application.a/webapp/test.js" - ]; - matchGlobResult(t, resources, expectedFiles); - }); -}); - -test("GLOB only a specific filetype (json) with exclude pattern from memory", (t) => { - t.plan(3); - return t.context.readerWriter.fromMemory([ - "/**/*.json", - "!/**/*package.json" - ]).then((resources) => { - const expectedFiles = [ - "/test-resources/application.b/webapp/manifest.json", - "/test-resources/application.b/webapp/embedded/manifest.json" - ]; - matchGlobResult(t, resources, expectedFiles); - }); -}); - -test("GLOB only a specific filetype (json) with multiple exclude pattern from memory", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory([ - "/**/*.json", - "!/**/*package.json", - "!/**/embedded/manifest.json" - ]).then((resources) => { - matchGlobResult(t, resources, ["/test-resources/application.b/webapp/manifest.json"]); - }); -}); - -test("GLOB (normalized) root directory (=> fs root)", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory([ - "/*/", - ], {nodir: false}).then((resources) => { - resources.forEach((res) => { - t.deepEqual(res._name, "test-resources"); - t.deepEqual(res.getStatInfo().isDirectory(), true); - }); - }); -}); - -test("GLOB root directory from memory", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory("/test-resources/", {nodir: false}) - .then((resources) => { - matchGlobResult(t, resources, ["/test-resources"]); - }); -}); - -test("GLOB subdirectory from memory", (t) => { - t.plan(2); - return t.context.readerWriter.fromMemory([ - "/test-resources/app*a", - ], {nodir: false}).then((resources) => { - resources.forEach((res) => { - t.deepEqual(res._name, "application.a"); - t.deepEqual(res.getStatInfo().isDirectory(), true); - }); - }); -}); diff --git a/test/lib/resources.js b/test/lib/resources.js index 1310e765..8aa9ed35 100644 --- a/test/lib/resources.js +++ b/test/lib/resources.js @@ -5,8 +5,58 @@ chai.use(require("chai-fs")); const assert = chai.assert; const ui5Fs = require("../../"); - const applicationBPath = path.join(__dirname, "..", "fixtures", "application.b"); + +// Create readerWriters before running tests +test.beforeEach((t) => { + t.context.readerWriters = { + source: ui5Fs.resourceFactory.createAdapter({ + fsBasePath: "./test/fixtures/application.a/webapp", + virBasePath: "/app/" + }), + dest: ui5Fs.resourceFactory.createAdapter({ + fsBasePath: "./test/tmp/readerWriters/application.a", + virBasePath: "/dest/" + }) + }; +}); + +/* BEWARE: + Always make sure that every test writes to a separate file! By default, tests are running concurrent. +*/ +test("Get resource from application.a (/index.html) and write it to /dest/ using a ReadableStream", (t) => { + const readerWriters = t.context.readerWriters; + // Get resource from one readerWriter + return t.notThrows(readerWriters.source.byPath("/app/index.html") + .then(function(resource) { + return resource.clone(); + }) + .then(function(newResource) { + // Write resource content to another readerWriter + newResource.setPath("/dest/index_readableStreamTest.html"); + return readerWriters.dest.write(newResource); + }).then(() => { + assert.fileEqual("./test/tmp/readerWriters/application.a/index_readableStreamTest.html", + "./test/fixtures/application.a/webapp/index.html"); + })); +}); + +test("createCollectionsForTree", (t) => { + // Creates resource reader collections for a given tree + const resourceReaders = ui5Fs.resourceFactory.createCollectionsForTree(applicationBTree); + + t.pass("Resource Readers created"); + + // Check whether resulting object contains both, + // resource readers for the application source itself and for its dependencies. + t.true(resourceReaders.hasOwnProperty("source"), "Contains readers for the application code"); + t.true(resourceReaders.hasOwnProperty("dependencies"), "Contains readers for the application's dependencies"); + + t.true(resourceReaders.source._readers.length === 1, "One reader for the application code"); + t.true(resourceReaders.dependencies._readers.length === 8, "Eight readers for the application's dependencies"); +}); + +/* Test data */ const applicationBTree = { "id": "application.b", "version": "1.0.0", @@ -132,123 +182,3 @@ const applicationBTree = { } } }; - -// Create readerWriters before running tests -test.beforeEach((t) => { - t.context.readerWriters = { - source: ui5Fs.resourceFactory.createAdapter({ - fsBasePath: "./test/fixtures/application.a/webapp", - virBasePath: "/app/" - }), - dest: ui5Fs.resourceFactory.createAdapter({ - fsBasePath: "./test/tmp/readerWriters/application.a", - virBasePath: "/dest/" - }) - }; -}); - -/* BEWARE: - Always make sure that every test writes to a separate file! By default, tests are running concurrent. -*/ - -test("Get resource from application.a (/index.html) and write it to /dest/ using a ReadableStream", (t) => { - const readerWriters = t.context.readerWriters; - // Get resource from one readerWriter - return t.notThrows(readerWriters.source.byPath("/app/index.html") - .then(function(resource) { - return resource.clone(); - }) - .then(function(newResource) { - // Write resource content to another readerWriter - newResource.setPath("/dest/index_readableStreamTest.html"); - return readerWriters.dest.write(newResource); - }).then(() => { - assert.fileEqual("./test/tmp/readerWriters/application.a/index_readableStreamTest.html", - "./test/fixtures/application.a/webapp/index.html"); - })); -}); - -test("FS RL: GLOB resources from application.a w/ virtual base path prefix", (t) => { - const readerWriters = t.context.readerWriters; - // Get resource from one readerWriter - return t.notThrows(readerWriters.source.byGlob("/app/**/*.html").then(function(resources) { - t.deepEqual(resources.length, 1, "Found exactly one resource"); - })); -}); - -test("FS RL: GLOB resources from application.a w/o virtual base path prefix", (t) => { - const readerWriters = t.context.readerWriters; - // Get resource from one readerWriter - return t.notThrows(readerWriters.source.byGlob("/**/*.html").then(function(resources) { - t.deepEqual(resources.length, 1, "Found exactly one resource"); - })); -}); - -test("Virtual RL: GLOB resources from application.a w/ virtual base path prefix", (t) => { - const readerWriter = ui5Fs.resourceFactory.createAdapter({ - virBasePath: "/app/" - }); - - const resource = ui5Fs.resourceFactory.createResource({ - path: "/app/index.html", - string: "test" - }); - - // Get resource from one readerWriter - return t.notThrows(readerWriter.write(resource) - .then(() => readerWriter.byGlob("/app/*.html")) - .then((resources) => { - t.deepEqual(resources.length, 1, "Found exactly one resource"); - }) - ); -}); - -test("Virtual RL: GLOB resources from application.a w/o virtual base path prefix", (t) => { - const readerWriter = ui5Fs.resourceFactory.createAdapter({ - virBasePath: "/app/" - }); - - const resource = ui5Fs.resourceFactory.createResource({ - path: "/app/index.html", - string: "test" - }); - - // Get resource from one readerWriter - return t.notThrows(readerWriter.write(resource) - .then(() => readerWriter.byGlob("/**/*.html")) - .then((resources) => { - t.deepEqual(resources.length, 1, "Found exactly one resource"); - }) - ); -}); - -test("Virtual RL: GLOB virtual directory w/o virtual base path prefix", (t) => { - // TODO: Add similar test (globbing on empty directory) for FS RL - // TODO: Also add tests for nodir: true option - const readerWriter = ui5Fs.resourceFactory.createAdapter({ - virBasePath: "/app/" - }); - - // Get resource from one readerWriter - return t.notThrows( - readerWriter.byGlob("/*", {nodir: false}) - .then((resources) => { - t.deepEqual(resources.length, 1, "Found exactly one resource"); - }) - ); -}); - -test("createCollectionsForTree", (t) => { - // Creates resource reader collections for a given tree - const resourceReaders = ui5Fs.resourceFactory.createCollectionsForTree(applicationBTree); - - t.pass("Resource Readers created"); - - // Check whether resulting object contains both, - // resource readers for the application source itself and for its dependencies. - t.true(resourceReaders.hasOwnProperty("source"), "Contains readers for the application code"); - t.true(resourceReaders.hasOwnProperty("dependencies"), "Contains readers for the application's dependencies"); - - t.true(resourceReaders.source._readers.length === 1, "One reader for the application code"); - t.true(resourceReaders.dependencies._readers.length === 8, "Eight readers for the application's dependencies"); -});