Skip to content

Commit

Permalink
Add part of tests for src/tasks/libraries-db.js task module
Browse files Browse the repository at this point in the history
  • Loading branch information
tormozz48 committed Jul 14, 2015
1 parent fdaab36 commit bcc9642
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 29 deletions.
98 changes: 72 additions & 26 deletions src/tasks/libraries-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,33 @@ module.exports = {
* Returns db hint object for improve db calls
* @param {TargetNodes} target object
* @returns {{gte: (TargetBase.KEY.NODE_PREFIX|*), lt: (TargetBase.KEY.PEOPLE_PREFIX|*), fillCache: boolean}}
* @private
*/
_getDbHints: function (target) {
/*
* Возвращает объект: {
* gte: 'nodes:',
* lt: 'people:'
* fillCache: true
* }
* Он необходим для того, чтобы выбирались только ключи имя которых "больше" nodes: и меньше "people:"
* Это позволяет ускорить процесс такой выборки так как ключи в базе отсортированы в алфавитном порядке
*/
return { gte: target.KEY.NODE_PREFIX, lt: target.KEY.PEOPLE_PREFIX, fillCache: true };
},

/**
* Returns array of library nodes from database
* @param {TargetBase} target object
* @returns {*}
* @returns {Promise}
* @private
*/
_getRootLibNodes: function (target) {
// возвращает записи в базе которые соответствуют корневым страницам библиотек к которым
// привязываются все страницы версий к которым в свою очередь привязываются страницы
// документов библиотеки, уровней переопределения и.т.д.
// Критерий выборки - наличие поля lib (прописывается в js модели).
// Значение поля lib - название библиотеки
return levelDb
.get().getByCriteria(function (record) {
// criteria - is existed field lib
Expand All @@ -42,33 +58,50 @@ module.exports = {
* Returns array of library version nodes from database
* @param {TargetNodes} target object
* @param {Object} lib - database record of library node
* @returns {*}
* @returns {Promise}
* @private
*/
_getLibVersionNodes: function (target, lib) {
// В этот метод передаются значения записей в базе данных
// которые соответствуют корневым страницам библиотек
// По критерию выбираются дочерние узлы библиотеки, которые являются ее версиями
return levelDb.get().getByCriteria(function (record) {
var key = record.key,
value = record.value;

if (key.indexOf(target.KEY.NODE_PREFIX) < 0) {
return false;
}
var value = record.value;

// criteria is equality of parent and id fields of version and library nodes
return value.parent === lib.id;
}, this.getDbHints(target));
return value.parent && value.parent === lib.id;
}, this._getDbHints(target));
},

/**
* Removes all library version records
* @param {TargetNodes} target object
* @param {Array} libVersions - array of objects with fields: "lib" and "version"
* @returns {Promise}
* @private
*/
_removeLibVersionsFromDb: function (target, libVersions) {
libVersions = libVersions.reduce(function (prev, item) {
prev[item.lib] = prev[item.lib] || [];
prev[item.lib].push(item.version);
return prev;
}, {});

// Удаление всех записей из базы данных, которые относятся к определенной версии библиотеки:
// документов библиотеки, уровней переопределения и блоков
return levelDb.get().removeByCriteria(function (dbRecord) {
var value = dbRecord.value,
route,
conditions;

// здесь критерием является совпадение условий
// 1. наличие у записи поля route
// 2. наличие поля route.conditions
// 3. наличие поля route.conditions.lib
// 4. наличие поля route.conditions.version
// 5. отсутствие поля lib (не удаляем корневые страницы библиотек, хотя это условие лишнее)
// 6. наличие route.conditions.lib в списке библиотек на удаление и
// route.conditions.version в списке версий библиоки на удаление
route = value.route;
if (!route) {
return false;
Expand All @@ -83,13 +116,19 @@ module.exports = {
return false;
}

if (!conditions.lib || !conditions.version) {
return false;
}

if (libVersions[conditions.lib] &&
libVersions[conditions.lib].indexOf(conditions.version) > -1) {
logger.debug(
util.format('rm from db lib: => %s version: => %s', conditions.lib, conditions.version), module);
return true;
}

// TODO не удаляются записи документации и jsdoc по блокам из-за чего база со временем раздувается Нужно решить это в рамках отдельной задачи

return false;
}, this._getDbHints(target));
},
Expand Down Expand Up @@ -149,8 +188,8 @@ module.exports = {
},

_compareVersions: function(a, b) {
var BRANCHES = ['master', 'dev'],
VERSION_REGEXP = /^\d+\.\d+\.\d+$/;
var BRANCHES = ['master', 'dev'],
VERSION_REGEXP = /^\d+\.\d+\.\d+$/;

if (BRANCHES.indexOf(a) !== -1) { return 1; }
if (BRANCHES.indexOf(b) !== -1) { return -1; }
Expand Down Expand Up @@ -198,6 +237,26 @@ module.exports = {
}, this);
},

/**
* Fill addLibVersions by all library versions from MDS registry.json file
* @returns {Array} array of objects with fields: "lib" and "version"
* @private
*/
_addAllFromRegistry: function () {
var registry = fsExtra.readJSONFileSync(path.join(target.LIBRARIES_FILE_PATH, 'registry.json')),
result = [];
Object.keys(registry).forEach(function (lib) {
if(!registry[lib] || !registry[lib].versions) {
return;
}

Object.keys(registry[lib].versions).forEach(function (version) {
result.push({ lib: lib, version: version });
});
});
return result;
},

run: function (target) {
var libChanges = target.getChanges().getLibraries(),
addLibVersions = [],
Expand All @@ -211,20 +270,7 @@ module.exports = {
.concat(libChanges.getRemoved())
.concat(libChanges.getModified())
} else {
var registry = fsExtra.readJSONFileSync(path.join(target.LIBRARIES_FILE_PATH, 'registry.json'));
addLibVersions = (function (registry) {
var result = [];
Object.keys(registry).forEach(function (lib) {
if(!registry[lib] || !registry[lib].versions) {
return;
}

Object.keys(registry[lib].versions).forEach(function (version) {
result.push({ lib: lib, version: version });
});
});
return result;
})(registry);
addLibVersions = this._addAllFromRegistry();
}

return vow.when(true)
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ require('./util.js');
require('./providers/level-db.js');

require('./tasks/libraries-files');
require('./tasks/libraries-db');
172 changes: 169 additions & 3 deletions test/tasks/libraries-db.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,169 @@
/**
* Created by bemer on 13.07.15.
*/
var fs = require('fs'),
path = require('path'),
vow = require('vow'),
should = require('should'),
fsExtra = require('fs-extra'),
levelDb = require('../../src/providers/level-db'),
Target = require('../../src/targets/nodes'),
task = require('../../src/tasks/libraries-db');

describe('libraries-db', function () {
describe('methods', function () {
var target, cacheFolder, dbFolder;

before(function () {
dbFolder = path.join(process.cwd(), './db');
fsExtra.mkdirpSync(dbFolder);
levelDb.init(dbFolder);
});

beforeEach(function () {
target = new Target({});
cacheFolder = path.join(process.cwd(), './cache');
fsExtra.mkdirsSync(cacheFolder);
});

afterEach(function () {
fsExtra.removeSync(cacheFolder);
});

after(function () {
fsExtra.removeSync(dbFolder);
});

describe('_getDbHints', function () {
it('should return valid db hints object', function () {
should.deepEqual(task._getDbHints(target), { fillCache: true, gte: 'nodes:', lt: 'people:' });
});
});

describe('_getRootLibNodes', function () {
it('should return empty list of root library nodes', function () {
return task._getRootLibNodes(target).then(function (result) {
result.should.be.instanceOf(Array).and.have.length(0);
})
});

it('should return valid list of root library nodes', function () {
return levelDb.get().batch([
{ type: 'put', key: 'nodes:1', value: { id: 'nodes:1', lib: 'bem-core' } },
{ type: 'put', key: 'nodes:2', value: { id: 'nodes:2', name: 'non-library1' } },
{ type: 'put', key: 'nodes:3', value: { id: 'nodes:3', lib: 'bem-components' } },
{ type: 'put', key: 'nodes:4', value: { id: 'nodes:4', name: 'non-library2 '} },
{ type: 'put', key: 'nodes:5', value: { id: 'nodes:5', lib: 'bem-bl' } }
])
.then(function () {
return task._getRootLibNodes(target);
})
.then(function (result) {
should.deepEqual(result, [
{ key: 'nodes:1', value: { id: 'nodes:1', lib: 'bem-core' } },
{ key: 'nodes:3', value: { id: 'nodes:3', lib: 'bem-components' } },
{ key: 'nodes:5', value: { id: 'nodes:5', lib: 'bem-bl' } }
]);
});
});

after(function () {
return levelDb.get().batch([
{ type: 'del', key: 'nodes:1' },
{ type: 'del', key: 'nodes:2' },
{ type: 'del', key: 'nodes:3' },
{ type: 'del', key: 'nodes:4' },
{ type: 'del', key: 'nodes:5' }
]);
})
});

describe('_getLibVersionNodes', function () {
it('should return empty list of lib version nodes', function () {
return task._getLibVersionNodes(target, 'bem-core').then(function (result) {
result.should.be.instanceOf(Array).and.have.length(0);
})
});

it('should return valid list of lib version nodes', function () {
return levelDb.get().batch([
{ type: 'put', key: 'nodes:11', value: { parent: 'nodes:1' } },
{ type: 'put', key: 'nodes:12', value: { parent: 'nodes:1' } },
{ type: 'put', key: 'nodes:13', value: { parent: 'nodes:2' } },
{ type: 'put', key: 'nodes:14', value: { parent: 'nodes:3' } }
])
.then(function () {
return task._getLibVersionNodes(target, { id: 'nodes:1' });
})
.then(function (result) {
should.deepEqual(result, [
{key: 'nodes:11', value: {parent: 'nodes:1'}},
{key: 'nodes:12', value: {parent: 'nodes:1'}}
]);
});
});

after(function () {
return levelDb.get().batch([
{ type: 'del', key: 'nodes:11' },
{ type: 'del', key: 'nodes:12' },
{ type: 'del', key: 'nodes:13' },
{ type: 'del', key: 'nodes:14' }
]);
});
});

describe('_removeLibVersionsFromDb', function () {
before(function () {
var records = [11, 12, 13, 14, 15].map(function (item) {
var key = 'nodes:' + item,
value = {
route: {
conditions: {
lib: 'bem-core',
version: 'v0.0.' + item%2
}
}
};
return { key: key, value: value };
});

records = records
.concat({ key: 'nodes:7', value: {} })
.concat({ key: 'nodes:8', value: { route: {} } })
.concat({ key: 'nodes:9', value: { route: { conditions: {} } } })
.concat({ key: 'nodes:10', value: { lib: 'bem-core' } });

return levelDb.get().batch(records.map(function (record) {
record.type = 'put';
return record;
}));
});

it('should remove given library versions from database', function () {
return levelDb.get().getByCriteria(function () { return true; }, {})
.then(function (result) {
return result.should.have.length(9);
})
.then(function () {
return task._removeLibVersionsFromDb(target, [
{ lib: 'bem-core', version: 'v0.0.0' },
{ lib: 'bem-core', version: 'v0.0.1' }
]);
})
.then(function () {
return levelDb.get().getByCriteria(function () { return true; }, {});
})
.then(function (result) {
result.should.have.length(4);
});
});

after(function () {
return levelDb.get().batch([
{ type: 'del', key: 'nodes:7' },
{ type: 'del', key: 'nodes:8' },
{ type: 'del', key: 'nodes:9' },
{ type: 'del', key: 'nodes:10' }
]);
});
});
});
});

0 comments on commit bcc9642

Please sign in to comment.