Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fs-tree-diff

Package Overview
Dependencies
Maintainers
2
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-tree-diff - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

.jshintrc

128

lib/index.js

@@ -6,20 +6,11 @@ 'use strict';

var Set = require('fast-ordered-set');
var Entries = require('./entries');
var util = require('./util');
var Tree = require('./tree');
var EntryTree = require('./entry-tree');
var Entry = require('./entry');
var byRelativePath = util.byRelativePath;
var ARBITRARY_START_OF_TIME = 0;
module.exports = FSTree;
function createEntriesMap(entries) {
var _ret = {};
entries.forEach(function(entry) {
_ret[entry.relativePath] = entry;
});
return _ret;
}
function toChangeOp(change) {

@@ -32,10 +23,26 @@ return ['change', change.relativePath];

this.files = new Set((options.files || []).slice());
this.entriesMap = createEntriesMap(options.entries || []);
this.entries = options.entries;
if (options._entries) {
this.entries = options._entries;
} else {
this.entries = new Set(options.entries || [], 'relativePath');
}
}
FSTree.fromPaths = function (paths) {
var entries = paths.map(function (path) {
return new Entry(path, 0, ARBITRARY_START_OF_TIME);
});
return new FSTree({
entries: entries,
});
};
FSTree._fromOwnSet = function(set) {
return new FSTree({ _entries: set });
};
Object.defineProperty(FSTree.prototype, 'size', {
get: function() {
return this.files.size;
return this.entries.size;
}

@@ -45,58 +52,40 @@ });

FSTree.prototype.forEach = function (fn, context) {
this.files.forEach(fn, context);
this.entries.forEach(fn, context);
};
FSTree.prototype.calculatePatch = function (_files) {
var createOps, removeOps, changeOps, tree;
if (this.entries) {
var _entries = _files;
tree = new EntryTree(this.entries);
var entries = new Entries(this.entries);
FSTree.prototype.difference = function(otherFSTree) {
return FSTree._fromOwnSet(this.entries.difference(otherFSTree.entries));
};
var removals = entries.remove(_entries);
var additions = entries.add(_entries);
var updates = entries.update(_entries);
FSTree.prototype.intersection = function(otherFSTree) {
return FSTree._fromOwnSet(this.entries.intersection(otherFSTree.entries));
};
tree.addFiles(additions.map(byRelativePath));
tree.removeFiles(removals.map(byRelativePath));
FSTree.prototype.calculatePatch = function (otherFSTree) {
// TODO: algorithimic complexity here isn't ideal. Future work can reduce
// that cost. Today, the FS IO operations outweigh the cost, even with a
// naive implementation
var tree = new Tree(this.entries);
removeOps = tree.postOrderDepthReducer(reduceRemovals, []);
createOps = tree.preOrderDepthReducer(reduceAdditions, []);
changeOps = updates.map(toChangeOp);
var fsRemoveTree = this.difference(otherFSTree);
var fsAddTree = otherFSTree.difference(this);
this.entries = _entries;
return removeOps.concat(createOps, changeOps);
// TODO: removeEntries should be combined with the postOrderDepthReducer and return removeOps
tree.removeEntries(fsRemoveTree.entries);
var removeOps = tree.postOrderDepthReducer(reduceRemovals, []);
} else {
// TODO: addEntries should be combined with th preOrderDepthReducer and return addOps
tree.addEntries(fsAddTree.entries);
var createOps = tree.preOrderDepthReducer(reduceAdditions, []);
// TODO: algorithimic complexity here isn't ideal. Future work can reduce
// that cost. Today, the FS IO operations outweigh the cost, even with a
// naive implementation
tree = new Tree(this.files.values);
var changes = this._findChanges(otherFSTree).map(function(change) {
return ['change', change];
});
var files = _files instanceof this.constructor ? _files.files : new Set(_files);
var filesToRemove = this.files.subtract(files).values;
var filesToAdd = files.subtract(this.files).values;
// TODO: removeFiles should be combined with the postOrderDepthReducer and return removeOps
tree.removeFiles(filesToRemove);
removeOps = tree.postOrderDepthReducer(reduceRemovals, []);
// TODO: addFiles should be combined with th preOrderDepthReducer and return removeOps
tree.addFiles(filesToAdd);
createOps = tree.preOrderDepthReducer(reduceAdditions, []);
var changes = findChanges(this.files, files).map(function(change) {
return ['change', change];
});
return removeOps.concat(createOps).concat(changes);
}
return removeOps.concat(createOps).concat(changes);
};
function findChanges(previousFiles, nextFiles) {
var a = previousFiles.intersection(nextFiles).values;
var b = nextFiles.intersection(previousFiles).values;
FSTree.prototype._findChanges = function(nextTree) {
var a = this.intersection(nextTree).entries.values;
var b = nextTree.intersection(this).entries.values;

@@ -109,9 +98,4 @@ if (a.length !== b.length) {

for (var i = 0; i < a.length; i++) {
// TODO: just to ensure expectations, but this will change when we
// introduce complex types
if (a[i] !== b[i]) {
throw new Error('EWUT');
}
if (needsUpdate(a[i], b[i])) {
changes.push(b);
changes.push(b[i].relativePath);
}

@@ -124,3 +108,9 @@ }

function needsUpdate(before, after) {
return false;
if (before.isDirectory() && after.isDirectory()) {
return false;
}
return before.size !== after.size ||
before.mtime !== after.mtime ||
before.mode !== after.mode;
}

@@ -177,2 +167,2 @@

}
}
}
'use strict';
function Tree(files, path, isNew) {
var Set = require('fast-ordered-set');
var Entry = require('./entry');
var chomp = require('./util').chomp;
var ARBITRARY_START_OF_TIME = 0;
function Tree(entries, path, isNew) {
this.children = { };

@@ -10,9 +16,5 @@ this.operation = null;

if (!Array.isArray(files)) {
throw new Error('new Tree must be given a files argument');
if (entries.size > 0) {
this.addEntries(entries, this.isNew);
}
if (files.length > 0) {
this.addFiles(files, this.isNew);
}
}

@@ -62,20 +64,20 @@

Tree.prototype.addFiles = function (files, _isNew) {
Tree.prototype.addEntries = function (entries, _isNew) {
var isNew = arguments.length > 1 ? arguments[1] : true;
files.map(function (file) {
return file.split('/');
}).forEach(function(file) {
this.addFile(file, isNew);
entries.forEach(function(entry) {
this.addEntry(entry, isNew);
}, this);
};
function File(current, isNew) {
function File(entry, isNew) {
this.isFile = true;
this.isNew = isNew;
this.name = current;
this.entry = entry;
this.operation = undefined;
// TODO: error if entry is a directory
}
Tree.prototype.addFile = function (fileParts, _isNew) {
Tree.prototype.addEntry = function (entry, _isNew) {
var fileParts = entry.relativePath.split('/');
var current = fileParts.shift();

@@ -85,2 +87,6 @@ var child = this.children[current];

if (current === '') {
return;
}
if (fileParts.length === 0) {

@@ -94,3 +100,3 @@ if (child && child.isFile) {

// add a file
this.children[current] = new File(current, isNew);
this.children[current] = new File(entry, isNew);
} else {

@@ -103,7 +109,7 @@ if (child && child.isFile) {

if (!tree) {
this.children[current] = new Tree([
fileParts.join('/')
], this.pathForChild(current), isNew);
this.children[current] = new Tree(new Set([
new Entry( fileParts.join('/'), 0, ARBITRARY_START_OF_TIME)
], 'relativePath'), this.pathForChild(current), isNew);
} else {
tree.addFile(fileParts, isNew);
tree.addEntry(new Entry(fileParts.join('/'), entry.size, entry.mtime), isNew);
}

@@ -113,9 +119,8 @@ }

Tree.prototype.removeFiles = function (files) {
files.map(function (file) {
return file.split('/');
}).forEach(this.removeFile, this);
Tree.prototype.removeEntries = function (entries) {
entries.forEach(this.removeEntry, this);
};
Tree.prototype.removeFile = function (fileParts) {
Tree.prototype.removeEntry = function (entry) {
var fileParts = chomp(entry.relativePath, '/').split('/');
var current = fileParts.shift();

@@ -137,6 +142,7 @@ var child = this.children[current];

child.removeFile(fileParts);
child.removeEntry(new Entry(fileParts.join('/'), null, null));
}
};
module.exports = Tree;

@@ -7,2 +7,11 @@ 'use strict';

module.exports.byRelativePath = byRelativePath;
function chomp(string, character) {
if (string.charAt(string.length-1) === character) {
return string.substring(0, string.length-1);
} else {
return string;
}
}
module.exports.byRelativePath = byRelativePath;
module.exports.chomp = chomp;
{
"name": "fs-tree-diff",
"version": "0.0.1",
"version": "0.1.0",
"description": "Backs out file tree changes",

@@ -16,3 +16,3 @@ "main": "lib/index.js",

"dependencies": {
"fast-ordered-set": "^1.0.1"
"fast-ordered-set": "^1.0.2"
},

@@ -19,0 +19,0 @@ "devDependencies": {

@@ -5,4 +5,2 @@ 'use strict';

var FSTree = require('../lib/index');
var Entries = require('../lib/entries');
var context = describe;

@@ -12,2 +10,15 @@ var fsTree;

describe('FSTree', function() {
function entry(options) {
return {
relativePath: options.relativePath,
mode: options.mode,
size: options.size,
mtime: options.mtime,
isDirectory: function() {
return (this.mode & 61440) === 16384;
}
};
};
it('can be instantiated', function() {

@@ -17,180 +28,35 @@ expect(new FSTree()).to.be.an.instanceOf(FSTree);

describe('Entries', function() {
var entries;
beforeEach(function() {
entries = new Entries([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
describe('.fromPaths', function() {
it('creates empty trees', function() {
fsTree = FSTree.fromPaths([ ]);
expect(fsTree.size).to.eq(0);
});
context('identity', function() {
it('should return the initial entries', function() {
expect(entries.identity()).to.deep.equal([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
});
});
it('creates trees from paths', function() {
var result;
context('add', function() {
it('should return the added files', function() {
var result = entries.add([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 },
{ relativePath: 'c.js', mode: '0o666', size: 1, mtime: 1 }
]);
fsTree = FSTree.fromPaths([
'a.js',
'foo/a.js',
]);
expect(result).to.deep.equal([
{ relativePath: 'c.js', mode: '0o666', size: 1, mtime: 1 }
]);
});
result = fsTree.calculatePatch(
FSTree.fromPaths([
'a.js',
'foo/b.js',
])
);
it('should handle directories', function() {
var result = entries.add([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 },
{ relativePath: 'c.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'f/', mode: '16384', size: 1, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'c.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'f/', mode: '16384', size: 1, mtime: 1 }
]);
});
it('should return an empty array if there is a mismatch', function() {
var result = entries.add([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
it('should return an empty array if there are no changes', function() {
var result = entries.add([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
expect(result).to.deep.equal([
['unlink', 'foo/a.js'],
// This no-op is not fundamental: a future iteration could reasonably
// optimize it away
['rmdir', 'foo'],
['mkdir', 'foo'],
['create', 'foo/b.js'],
]);
});
context('remove', function() {
it('should find the removals', function () {
var result = entries.remove([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
});
it('should find directory removals', function () {
var localEntries = new Entries([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'c/', mode: '16384', size: 1, mtime: 1 },
{ relativePath: 'c/c.js', mode: '0o666', size: 1, mtime: 1 }
]);
var result = localEntries.remove([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'c/', mode: '16384', size: 1, mtime: 1 },
{ relativePath: 'c/c.js', mode: '0o666', size: 1, mtime: 1 }
]);
});
it('should return an empty array if the file length is the same', function() {
var result = entries.remove([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
it('should return an empty array if their are additions', function() {
var result = entries.remove([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 },
{ relativePath: 'c.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
});
context('update', function() {
it('should diff by size', function() {
var result = entries.update([
{ relativePath: 'a/b.js', mode: '0o666', size: 10, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'a/b.js', mode: '0o666', size: 10, mtime: 1 }
]);
});
it('should diff by mtime (Number)', function() {
var result = entries.update([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 10 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 10 }
]);
});
it('should diff by mtime (Date)', function() {
var date = new Date(10);
var result = entries.update([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: date },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: date }
]);
});
it('should diff by mode', function() {
var result = entries.update([
{ relativePath: 'a/b.js', mode: 'foo', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([
{ relativePath: 'a/b.js', mode: 'foo', size: 1, mtime: 1 }
]);
});
it('should return an empty array if their are additions', function() {
var result = entries.remove([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'b.js', mode: '0o666', size: 2, mtime: 1 },
{ relativePath: 'c.js', mode: '0o666', size: 2, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
it('should return an empty array if there are removals', function() {
var result = entries.add([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }
]);
expect(result).to.deep.equal([]);
});
});
});
describe('.calculatePatch', function() {
describe('#calculatePatch', function() {
context('from an empty tree', function() {

@@ -203,3 +69,3 @@ beforeEach( function() {

it('returns 0 operations', function() {
expect(fsTree.calculatePatch([])).to.deep.equal([]);
expect(fsTree.calculatePatch(FSTree.fromPaths([]))).to.deep.equal([]);
});

@@ -210,6 +76,6 @@ });

it('returns n create operations', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'bar/baz.js',
'foo.js',
])).to.deep.equal([
]))).to.deep.equal([
['mkdir', 'bar'],

@@ -225,8 +91,6 @@ ['create', 'foo.js'],

beforeEach( function() {
fsTree = new FSTree({
files: [
'bar/baz.js',
'foo.js',
],
});
fsTree = FSTree.fromPaths([
'bar/baz.js',
'foo.js',
]);
});

@@ -236,3 +100,3 @@

it('returns n rm operations', function() {
expect(fsTree.calculatePatch([])).to.deep.equal([
expect(fsTree.calculatePatch(FSTree.fromPaths([]))).to.deep.equal([
['unlink', 'bar/baz.js'],

@@ -250,5 +114,5 @@ ['rmdir', 'bar'],

entries: [
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'a/c.js', mode: '0o666', size: 1, mtime: 1 }
entry({ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'a/c.js', mode: '0o666', size: 1, mtime: 1 })
]

@@ -259,8 +123,10 @@ });

it('should detect additions', function() {
var result = fsTree.calculatePatch([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'a/c.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'a/j.js', mode: '0o666', size: 1, mtime: 1 }
]);
var result = fsTree.calculatePatch(new FSTree({
entries: [
entry({ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'a/c.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'a/j.js', mode: '0o666', size: 1, mtime: 1 })
]
}));

@@ -273,5 +139,7 @@ expect(result).to.deep.equal([

it('should detect removals', function() {
var result = fsTree.calculatePatch([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }
]);
var result = fsTree.calculatePatch(new FSTree({
entries: [
entry({ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 })
]
}));

@@ -286,11 +154,13 @@ expect(result).to.deep.equal([

it('should detect updates', function() {
var result = fsTree.calculatePatch([
{ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 },
{ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 2 },
{ relativePath: 'a/c.js', mode: '0o666', size: 10, mtime: 1 }
]);
var result = fsTree.calculatePatch(new FSTree({
entries: [
entry({ relativePath: 'a/b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'c/d.js', mode: '0o666', size: 1, mtime: 2 }),
entry({ relativePath: 'a/c.js', mode: '0o666', size: 10, mtime: 1 })
]
}));
expect(result).to.deep.equal([
['change', 'c/d.js'],
['change', 'a/c.js'],
['change', 'c/d.js']
]);

@@ -300,17 +170,49 @@ });

context('\w updates', function() {
context('FSTree with updates at several different depths', function () {
beforeEach( function() {
fsTree = new FSTree({
files: [
'bar/baz.js',
'foo.js',
],
entries: [
entry({ relativePath: 'a.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/a.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/two/a.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/two/b.js', mode: '0o666', size: 1, mtime: 1 }),
]
});
});
it('returns n rm operations', function() {
expect(fsTree.calculatePatch([
it('catches each update', function() {
var result = fsTree.calculatePatch(new FSTree({
entries: [
entry({ relativePath: 'a.js', mode: '0o666', size: 1, mtime: 2 }),
entry({ relativePath: 'b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/a.js', mode: '0o666', size: 10, mtime: 1 }),
entry({ relativePath: 'one/b.js', mode: '0o666', size: 1, mtime: 1 }),
entry({ relativePath: 'one/two/a.js', mode: '0o667', size: 1, mtime: 1 }),
entry({ relativePath: 'one/two/b.js', mode: '0o666', size: 1, mtime: 1 }),
]
}));
expect(result).to.deep.equal([
['change', 'a.js'],
['change', 'one/a.js'],
['change', 'one/two/a.js'],
]);
});
});
context('with only unchanged paths', function() {
beforeEach( function() {
fsTree = FSTree.fromPaths([
'bar/baz.js',
'foo.js',
]);
});
it('returns an empty changeset', function() {
expect(fsTree.calculatePatch(FSTree.fromPaths([
'bar/baz.js',
'foo.js'
])).to.deep.equal([
]))).to.deep.equal([
// when we work with entries, will potentially return updates

@@ -324,10 +226,8 @@ ]);

beforeEach( function() {
fsTree = new FSTree({
files: [
'foo/one.js',
'foo/two.js',
'bar/one.js',
'bar/two.js',
],
});
fsTree = FSTree.fromPaths([
'foo/one.js',
'foo/two.js',
'bar/one.js',
'bar/two.js',
]);
});

@@ -337,5 +237,5 @@

it('reduces the rm operations', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'bar/two.js'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'foo/one.js'],

@@ -351,5 +251,5 @@ ['unlink', 'foo/two.js'],

it('reduces the rm operations', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'bar/three.js'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'foo/one.js'],

@@ -377,8 +277,6 @@ ['unlink', 'foo/two.js'],

beforeEach( function() {
fsTree = new FSTree({
files: [
'bar/quz/baz.js',
'foo.js',
],
});
fsTree = FSTree.fromPaths([
'bar/quz/baz.js',
'foo.js',
]);
});

@@ -388,3 +286,3 @@

it('returns n rm operations', function() {
expect(fsTree.calculatePatch([])).to.deep.equal([
expect(fsTree.calculatePatch(FSTree.fromPaths([]))).to.deep.equal([
['unlink', 'bar/quz/baz.js'],

@@ -401,8 +299,6 @@ ['rmdir', 'bar/quz'],

beforeEach( function() {
fsTree = new FSTree({
files: [
'bar/quz/baz.js',
'bar/foo.js',
],
});
fsTree = FSTree.fromPaths([
'bar/quz/baz.js',
'bar/foo.js',
]);
});

@@ -412,5 +308,5 @@

it('returns one unlink operation', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'bar/quz/baz.js'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'bar/foo.js']

@@ -424,8 +320,6 @@ ]);

beforeEach( function() {
fsTree = new FSTree({
files: [
'subdir1/subsubdir1/foo.png',
'subdir2/bar.css'
],
});
fsTree = FSTree.fromPaths([
'subdir1/subsubdir1/foo.png',
'subdir2/bar.css'
]);
});

@@ -435,5 +329,5 @@

it('returns one unlink operation', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'subdir1/subsubdir1/foo.png'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'subdir2/bar.css'],

@@ -448,13 +342,11 @@ ['rmdir', 'subdir2']

beforeEach( function() {
fsTree = new FSTree({
files: [
'subdir1/foo'
],
});
fsTree = FSTree.fromPaths([
'subdir1/foo'
]);
});
it('it unlinks the file, and rmdir the folder and then creates the file', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'subdir1'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'subdir1/foo'],

@@ -469,13 +361,11 @@ ['rmdir', 'subdir1'],

beforeEach( function() {
fsTree = new FSTree({
files: [
'subdir1'
],
});
fsTree = FSTree.fromPaths([
'subdir1'
]);
});
it('it unlinks the file, and makes the folder and then creates the file', function() {
expect(fsTree.calculatePatch([
expect(fsTree.calculatePatch(FSTree.fromPaths([
'subdir1/foo'
])).to.deep.equal([
]))).to.deep.equal([
['unlink', 'subdir1'],

@@ -488,26 +378,30 @@ ['mkdir', 'subdir1'],

// context('only folders', function() {
// beforeEach( function() {
// fsTree = new FSTree({
// files: [
// 'dir/',
// 'dir2/subdir1/',
// 'dir3/subdir1/'
// ]
// });
// });
context('only folders', function() {
beforeEach( function() {
fsTree = FSTree.fromPaths([
'dir/',
'dir2/subdir1/',
'dir3/subdir1/'
]);
});
// it('it unlinks the file, and makes the folder and then creates the file', function() {
// expect(fsTree.calculatePatch([
// 'dir2/subdir1/',
// 'dir3/',
// 'dir4/',
// ])).to.deep.equal([
// ['rmdir', 'dir1'],
// ['rmdir', 'dir3/subdir1'],
// ['mkdir', 'dir4']
// ]);
// });
// });
it('it unlinks the file, and makes the folder and then creates the file', function() {
var result = fsTree.calculatePatch(FSTree.fromPaths([
'dir2/subdir1/',
'dir3/',
'dir4/',
]));
expect(result).to.deep.equal([
['rmdir', 'dir3/subdir1'],
['rmdir', 'dir'],
// This no-op (rmdir dir3; mkdir dir3) is not fundamental: a future
// iteration could reasonably optimize it away
['rmdir', 'dir3'],
['mkdir', 'dir3'],
['mkdir', 'dir4']
]);
});
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc