"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var chai_1 = require("chai");
var universal_1 = require("../src/universal");
var events_matcher_1 = require("../test-kit/drivers/events-matcher");
exports.dirName = 'foo';
exports.fileName = 'bar.txt';
exports.content = 'content';
exports.ignoredDir = 'ignored';
exports.ignoredFile = "" + exports.dirName + universal_1.pathSeparator + "ignored.txt";
function assertFileSystemContract(fsProvider, options) {
    describe("filesystem contract", function () {
        var fs;
        var matcher;
        beforeEach(function () {
            matcher = new events_matcher_1.EventsMatcher(options);
            return fsProvider()
                .then(function (newFs) {
                fs = newFs;
                matcher.track.apply(matcher, [fs.events].concat(universal_1.fileSystemEventNames));
            });
        });
        it("initially empty", function () {
            return chai_1.expect(fs.loadDirectoryTree()).to.become({ type: 'dir', name: '', fullPath: '', children: [] });
        });
        it("loading a non-existing file - fails", function () {
            return chai_1.expect(fs.loadTextFile(exports.fileName)).to.be.rejectedWith(Error);
        });
        it("loading a directory as a file - fails", function () {
            return fs.ensureDirectory(exports.dirName)
                .then(function () {
                return matcher.expect([{ type: 'directoryCreated', fullPath: exports.dirName }]);
            })
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.dirName)).to.be.rejectedWith(Error); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving an illegal file name - fails", function () {
            return chai_1.expect(fs.saveFile('', exports.content)).to.be.rejectedWith(Error)
                .then(function () { return matcher.expect([]); });
        });
        it("ensuring existence of directory", function () {
            var expectedStructure = {
                type: 'dir', name: '', fullPath: '', children: [
                    { type: 'dir', name: exports.dirName, fullPath: exports.dirName, children: [] }
                ]
            };
            return fs.ensureDirectory(exports.dirName)
                .then(function () { return matcher.expect([{ type: 'directoryCreated', fullPath: exports.dirName }]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become(expectedStructure); })
                .then(function () { return fs.ensureDirectory(exports.dirName); }) //2nd time does nothing
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become(expectedStructure); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving a file over a directory - fails", function () {
            return fs.ensureDirectory(exports.dirName)
                .then(function () { return matcher.expect([{ type: 'directoryCreated', fullPath: exports.dirName }]); })
                .then(function () { return chai_1.expect(fs.saveFile(exports.dirName, exports.content)).to.be.rejectedWith(Error); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become({
                type: 'dir', name: '', fullPath: '', children: [
                    { type: 'dir', name: exports.dirName, fullPath: exports.dirName, children: [] }
                ]
            }); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving a file over a file in its path - fails", function () {
            var fileNameAsDir = exports.dirName;
            return fs.saveFile(fileNameAsDir, exports.content)
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: fileNameAsDir, newContent: exports.content }]); })
                .then(function () { return chai_1.expect(fs.saveFile(fileNameAsDir + "/" + exports.fileName, '_${content}')).to.be.rejectedWith(Error); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become({
                type: 'dir', name: '', fullPath: '', children: [
                    { type: 'file', name: fileNameAsDir, fullPath: fileNameAsDir }
                ]
            }); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving a new file (and a new directory to hold it)", function () {
            return fs.saveFile(exports.dirName + "/" + exports.fileName, exports.content)
                .then(function () { return matcher.expect([{ type: 'directoryCreated', fullPath: exports.dirName }, { type: 'fileCreated', fullPath: exports.dirName + "/" + exports.fileName, newContent: exports.content }]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become({
                type: 'dir', name: '', fullPath: '', children: [
                    { type: 'dir', name: exports.dirName, fullPath: exports.dirName, children: [
                            { type: 'file', name: exports.fileName, fullPath: exports.dirName + "/" + exports.fileName }
                        ] }
                ]
            }); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving a file with different content", function () {
            var newContent = "_" + exports.content;
            return fs.saveFile(exports.fileName, exports.content)
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: exports.fileName, newContent: exports.content }]); })
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.fileName)).to.become(exports.content); })
                .then(function () { return fs.saveFile(exports.fileName, newContent); })
                .then(function () { return matcher.expect([{ type: 'fileChanged', fullPath: exports.fileName, newContent: newContent }]); })
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.fileName)).to.become(newContent); })
                .then(function () { return matcher.expect([]); });
        });
        it("saving a file with same content", function () {
            var expectedStructure = {
                type: 'dir', name: '', fullPath: '', children: [
                    { name: exports.fileName, fullPath: exports.fileName, type: 'file' }
                ]
            };
            return fs.saveFile(exports.fileName, exports.content)
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: exports.fileName, newContent: exports.content }]); })
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.fileName)).to.become(exports.content); })
                .then(function () { return fs.saveFile(exports.fileName, exports.content); }) // may or may not trigger an event
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.become(expectedStructure); })
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.fileName)).to.become(exports.content); });
        });
        it("deleting root directory - fails", function () {
            return chai_1.expect(fs.deleteDirectory('')).to.be.rejectedWith(Error)
                .then(function () { return matcher.expect([]); });
        });
        it("deleting a directory", function () {
            return fs.ensureDirectory(exports.dirName + "/_" + exports.dirName)
                .then(function () { return matcher.expect([
                { type: 'directoryCreated', fullPath: exports.dirName },
                { type: 'directoryCreated', fullPath: exports.dirName + "/_" + exports.dirName }
            ]); })
                .then(function () { return fs.deleteDirectory(exports.dirName + "/_" + exports.dirName); })
                .then(function () { return matcher.expect([{ type: 'directoryDeleted', fullPath: exports.dirName + "/_" + exports.dirName }]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([
                { children: [], fullPath: exports.dirName, name: exports.dirName, type: 'dir' }
            ]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting non existing directory succeeds", function () {
            return fs.deleteDirectory(exports.dirName + "/_" + exports.dirName)
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting directory which is actually a file - fails", function () {
            return fs.saveFile(exports.fileName, exports.content)
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: exports.fileName, newContent: exports.content }]); })
                .then(function () { return chai_1.expect(fs.deleteDirectory(exports.fileName)).to.be.rejectedWith(Error); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting non-empty directory without recursive flag - fails", function () {
            return fs.saveFile(exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, exports.content)
                .then(function () { return matcher.expect([
                { type: 'directoryCreated', fullPath: exports.dirName },
                { type: 'directoryCreated', fullPath: exports.dirName + "/_" + exports.dirName },
                { type: 'fileCreated', fullPath: exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, newContent: exports.content }
            ]); })
                .then(function () { return chai_1.expect(fs.deleteDirectory(exports.dirName + "/_" + exports.dirName)).to.be.rejectedWith(Error); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting non-empty directory with recursive flag", function () {
            var filePath = exports.dirName + "/_" + exports.dirName + "/" + exports.fileName;
            return fs.saveFile(filePath, exports.content)
                .then(function () { return matcher.expect([
                { type: 'directoryCreated', fullPath: exports.dirName },
                { type: 'directoryCreated', fullPath: exports.dirName + "/_" + exports.dirName },
                { type: 'fileCreated', fullPath: filePath, newContent: exports.content }
            ]); })
                .then(function () { return fs.deleteDirectory(exports.dirName, true); })
                .then(function () { return matcher.expect([
                { type: 'directoryDeleted', fullPath: exports.dirName },
                { type: 'fileDeleted', fullPath: filePath }
            ]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting file which is actually a directory - fails", function () {
            var dirNameAsFileName = exports.fileName;
            return fs.ensureDirectory(dirNameAsFileName)
                .then(function () { return matcher.expect([{ type: 'directoryCreated', fullPath: dirNameAsFileName }]); })
                .then(function () { return chai_1.expect(fs.deleteFile(dirNameAsFileName)).to.be.rejectedWith(Error); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting only one file", function () {
            return fs.saveFile(exports.fileName, exports.content)
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: exports.fileName, newContent: exports.content }]); })
                .then(function () { return fs.saveFile("_" + exports.fileName, "_" + exports.content); })
                .then(function () { return matcher.expect([{ type: 'fileCreated', fullPath: "_" + exports.fileName, newContent: "_" + exports.content }]); })
                .then(function () { return fs.deleteFile("_" + exports.fileName); })
                .then(function () { return matcher.expect([{ type: 'fileDeleted', fullPath: "_" + exports.fileName }]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([{ fullPath: exports.fileName, name: exports.fileName, type: 'file' }]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting non existing file succeeds", function () {
            return fs.deleteFile(exports.fileName)
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting non existing file (deep path) succeeds", function () {
            return fs.deleteFile(exports.dirName + "/" + exports.fileName)
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); })
                .then(function () { return matcher.expect([]); });
        });
        it("deleting ignored file succeeds", function () {
            return fs.deleteFile(exports.ignoredFile)
                .then(function () { return matcher.expect([]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); });
        });
        it("deleting ignored directory succeeds", function () {
            return fs.deleteDirectory(exports.ignoredDir)
                .then(function () { return matcher.expect([]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]); });
        });
        it("saving ignored file - fails", function () {
            return chai_1.expect(fs.saveFile(exports.ignoredFile, 'foo')).to.be.rejectedWith(Error);
        });
        it("saving ignored dir - fails", function () {
            return chai_1.expect(fs.ensureDirectory(exports.ignoredDir)).to.be.rejectedWith(Error);
        });
        it("loading existed ignored file - fails", function () {
            return fs.ensureDirectory(exports.dirName)
                .then(function () { return chai_1.expect(fs.loadTextFile(exports.ignoredFile)).to.be.rejectedWith(Error); });
        });
        it("loadDirectoryTree", function () {
            var expected = { fullPath: "", name: '', type: 'dir', children: [
                    { fullPath: "" + exports.dirName, name: exports.dirName, type: 'dir', children: [
                            { fullPath: exports.dirName + "/_" + exports.dirName, name: "_" + exports.dirName, type: 'dir', children: [
                                    { fullPath: exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, name: exports.fileName, type: 'file' }
                                ] }
                        ] }
                ] };
            return fs.saveFile(exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, exports.content)
                .then(function () { return chai_1.expect(fs.loadDirectoryTree()).to.eventually.eql(expected); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree(exports.dirName), "loadDirectoryTree('" + exports.dirName + "')").to.eventually.eql(expected.children[0]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryTree(exports.dirName + "/_" + exports.dirName), "loadDirectoryTree('" + exports.dirName + "/_" + exports.dirName + "')").to.eventually.eql(expected.children[0].children[0]); });
        });
        it("loadDirectoryTree on an illegal sub-path", function () {
            return chai_1.expect(fs.loadDirectoryTree(exports.fileName)).to.be.rejectedWith(Error);
        });
        it("loadDirectoryChildren", function () {
            return fs.saveFile(exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, exports.content)
                .then(function () { return fs.saveFile("" + exports.fileName, exports.content); })
                .then(function () { return chai_1.expect(fs.loadDirectoryChildren('')).to.eventually.have.deep.members([
                { fullPath: "" + exports.dirName, name: exports.dirName, type: 'dir' },
                { fullPath: exports.fileName, name: exports.fileName, type: 'file' }
            ]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryChildren(exports.dirName), "loadDirectoryChildren('" + exports.dirName + "')").to.eventually.have.deep.members([{ fullPath: exports.dirName + "/_" + exports.dirName, name: "_" + exports.dirName, type: 'dir' }]); })
                .then(function () { return chai_1.expect(fs.loadDirectoryChildren(exports.dirName + "/_" + exports.dirName), "loadDirectoryChildren('" + exports.dirName + "/_" + exports.dirName + "')").to.eventually.have.deep.members([{ fullPath: exports.dirName + "/_" + exports.dirName + "/" + exports.fileName, name: exports.fileName, type: 'file' }]); });
        });
        it("loadDirectoryChildren on an illegal sub-path", function () {
            return chai_1.expect(fs.loadDirectoryChildren(exports.fileName)).to.be.rejectedWith(Error);
        });
    });
}
exports.assertFileSystemContract = assertFileSystemContract;
//# sourceMappingURL=implementation-suite.js.map