"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tmp_1 = require("tmp");
var fs_1 = require("fs");
var path_1 = require("path");
var chai_1 = require("chai");
var implementation_suite_1 = require("./implementation-suite");
var events_matcher_1 = require("../test-kit/drivers/events-matcher");
var universal_1 = require("../src/universal");
var nodejs_1 = require("../src/nodejs");
describe("the local filesystem implementation", function () {
    var dirCleanup, rootPath, testPath;
    var counter = 0;
    var disposableFileSystem;
    before(function (done) {
        tmp_1.dir({ unsafeCleanup: true }, function (_err, path, cleanupCallback) {
            dirCleanup = cleanupCallback;
            rootPath = path;
            done();
        });
    });
    after(function () {
        try {
            dirCleanup();
        }
        catch (e) {
            console.log('cleanup error', e);
        }
    });
    afterEach(function () {
        // if beforeEach fails, disposableFileSystem can stay undefined
        disposableFileSystem && disposableFileSystem.dispose();
    });
    function getFS() {
        testPath = path_1.join(rootPath, 'fs_' + (counter++));
        fs_1.mkdirSync(testPath);
        disposableFileSystem = new nodejs_1.LocalFileSystem(testPath, [implementation_suite_1.ignoredDir, implementation_suite_1.ignoredFile]);
        return disposableFileSystem.init();
    }
    var eventMatcherOptions = {
        retries: 40,
        interval: 50,
        timeout: 2500,
        noExtraEventsGrace: 150
    };
    implementation_suite_1.assertFileSystemContract(getFS, eventMatcherOptions);
    describe("external changes", function () {
        var fs;
        var matcher;
        beforeEach(function () {
            matcher = new events_matcher_1.EventsMatcher(eventMatcherOptions);
            return getFS().then(function (newFs) {
                fs = newFs;
                matcher.track.apply(matcher, [fs.events].concat(universal_1.fileSystemEventNames));
            });
        });
        it("handles dir creation", function () {
            var path = path_1.join(testPath, implementation_suite_1.dirName);
            fs_1.mkdirSync(path);
            return chai_1.expect(fs.loadDirectoryTree())
                .to.eventually.have.property('children').eql([
                { children: [], fullPath: implementation_suite_1.dirName, name: implementation_suite_1.dirName, type: 'dir' }
            ]);
        });
        it("handles dir deletion", function () {
            var path = path_1.join(testPath, implementation_suite_1.dirName);
            fs_1.mkdirSync(path);
            fs_1.rmdirSync(path);
            return chai_1.expect(fs.loadDirectoryTree()).to.eventually.have.property('children').eql([]);
        });
        it("handles file creation", function () {
            var path = path_1.join(testPath, implementation_suite_1.fileName);
            fs_1.writeFileSync(path, implementation_suite_1.content);
            return chai_1.expect(fs.loadTextFile(implementation_suite_1.fileName)).to.eventually.equals(implementation_suite_1.content);
        });
        it("handles file deletion", function () {
            var path = path_1.join(testPath, implementation_suite_1.fileName);
            fs_1.writeFileSync(path, implementation_suite_1.content);
            fs_1.unlinkSync(path);
            return chai_1.expect(fs.loadTextFile(implementation_suite_1.fileName)).to.eventually.be.rejected;
        });
        it("handles file change", function () {
            var path = path_1.join(testPath, implementation_suite_1.fileName);
            var newContent = "_" + implementation_suite_1.content;
            fs_1.writeFileSync(path, implementation_suite_1.content);
            return matcher.expect([{ type: 'fileCreated', fullPath: implementation_suite_1.fileName, newContent: implementation_suite_1.content }])
                .then(function () {
                fs_1.writeFileSync(path, newContent);
                return Promise.resolve();
            })
                .then(function () { return chai_1.expect(fs.loadTextFile(implementation_suite_1.fileName)).to.eventually.equals(newContent); });
        });
        it("ignores events from ignored dir", function () {
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir));
            return matcher.expect([]);
        });
        it("ignores events from ignored file", function () {
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.dirName));
            return matcher.expect([{ type: 'directoryCreated', fullPath: implementation_suite_1.dirName }])
                .then(function () { return fs_1.writeFileSync(path_1.join(testPath, implementation_suite_1.ignoredFile), implementation_suite_1.content); })
                .then(function () { return matcher.expect([]); });
        });
        it("loadDirectoryTree() ignores ignored folder and file", function () {
            var expectedStructure = {
                name: '',
                type: 'dir',
                fullPath: '',
                children: [{ name: implementation_suite_1.dirName, type: 'dir', fullPath: implementation_suite_1.dirName, children: [] }]
            };
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.dirName));
            fs_1.writeFileSync(path_1.join(testPath, implementation_suite_1.ignoredFile), implementation_suite_1.content);
            return chai_1.expect(fs.loadDirectoryTree()).to.eventually.deep.equal(expectedStructure);
        });
        it("loadDirectoryTree() ignores ignored folder with special characters", function () {
            var expectedStructure = {
                name: '',
                type: 'dir',
                fullPath: '',
                children: [{ name: implementation_suite_1.dirName, type: 'dir', fullPath: implementation_suite_1.dirName, children: [] }]
            };
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir, 'name-with-dashes'));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir, 'name-with-dashes', '.name_starts_with_dot'));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir, 'name-with-dashes', '.name_starts_with_dot', '.name_starts_with_dot'));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.dirName));
            return chai_1.expect(fs.loadDirectoryTree()).to.eventually.deep.equal(expectedStructure);
        });
        it("ignores events in dot-folders and files", function () {
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir));
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.ignoredDir, "." + implementation_suite_1.dirName));
            fs_1.writeFileSync(path_1.join(testPath, implementation_suite_1.ignoredDir, "." + implementation_suite_1.dirName, "." + implementation_suite_1.fileName), implementation_suite_1.content);
            return matcher.expect([]);
        });
        it("loading existed ignored file - fails", function () {
            fs_1.mkdirSync(path_1.join(testPath, implementation_suite_1.dirName));
            fs_1.writeFileSync(path_1.join(testPath, implementation_suite_1.ignoredFile), implementation_suite_1.content);
            return chai_1.expect(fs.loadTextFile(implementation_suite_1.ignoredFile)).to.be.rejectedWith(Error);
        });
        it("emits 'unexpectedError' if 'loadTextFile' rejected in watcher 'add' callback", function () {
            fs.loadTextFile = function () { return Promise.reject('go away!'); };
            var path = path_1.join(testPath, implementation_suite_1.fileName);
            fs_1.writeFileSync(path, implementation_suite_1.content);
            return matcher.expect([{ type: 'unexpectedError' }]);
        });
        it("emits 'unexpectedError' if 'loadTextFile' rejected in watcher 'change' callback", function () {
            return fs.saveFile(implementation_suite_1.fileName, implementation_suite_1.content)
                .then(function () { return fs.loadTextFile = function () { return Promise.reject('go away!'); }; })
                .then(function () { return fs.saveFile(implementation_suite_1.fileName, "_" + implementation_suite_1.content); })
                .then(function () { return matcher.expect([{ type: 'unexpectedError' }]); });
        });
    });
});
//# sourceMappingURL=local-fs.spec.js.map